реклама на сайте
подробности

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> UART STM32F100Rxx и определение окончание приема "пакета" данных
alexdos
сообщение Mar 12 2013, 08:14
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 339
Регистрация: 10-07-08
Из: Херсон
Пользователь №: 38 856



По какому признаку можно определить что "пакет" данных в буфер по прерыванию принят. Данные идут от GPS приёмника, их количество не фиксировано. Тоесть может быть к примеру 146 байт, а может быть 152 байта.
Пробую через (USART_GetITStatus(USART2,USART_IT_IDLE) != RESET), но неверно определяет окончание приёма, данные не приняты все, а мне уже симафорит что принято.
Или по старинке, использовать таймер для определения окончания приёма?
Go to the top of the page
 
+Quote Post
uriy
сообщение Mar 12 2013, 08:39
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 429
Регистрация: 30-11-05
Из: Ижевск
Пользователь №: 11 606



Цитата
Тоесть может быть к примеру 146 байт, а может быть 152 байта.
Откуда контроллеру знать сколько байт в вашем пакете?
NMEA пакеты заканчиваются символом переноса строки, что вам мешает использовать этот признак?
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Mar 12 2013, 08:50
Сообщение #3


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Цитата(alexdos @ Mar 12 2013, 09:14) *
По какому признаку можно определить что "пакет" данных в буфер по прерыванию принят.
Пробую через (USART_GetITStatus(USART2,USART_IT_IDLE) != RESET),

Судя по приведенной функции у Вас совершенно искаженное представление об USART. Это устройство байтового типа, а "пакетом" для USART является последовательность бит. Как только предопределенный пакет бит принят, USART предоставляет байт для считывания. Боюсь, прежде, чем начать разбирать GPS (NMEA) пакеты, Вам придется основательно изучить принципы буферизируемого приема (и передачи) потока данный через байтное устройство.

Сообщение отредактировал KnightIgor - Mar 12 2013, 08:52
Go to the top of the page
 
+Quote Post
alexdos
сообщение Mar 12 2013, 09:36
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 339
Регистрация: 10-07-08
Из: Херсон
Пользователь №: 38 856



"NMEA пакеты заканчиваются символом переноса строки, что вам мешает использовать этот признак?" все верно, но мне нужно принять весь пакет данных отправляемый GPS приемником. Включающий в себя группу пакетов NMEA, каждый с которых оканчивается символом переноса строки. Вырезать каждый NMEA пакет я не хочу, хочу получить всю пачку, при этом потратив минимум ресурсов, а затем спокойно обработать.
KnightIgor Вы бы по сути сказали, а не высказывали предположения о моих познаниях. Чтото типа "так не делают" , а вот так делают. По приходу каждого байта по прерыванию (USART_GetITStatus(USART2,USART_IT_RXNE) != RESET) я этот байт складываю в буфер. Вот и спрашиваю в опытных, какой признак окончания приёма данных (пауза) будет достаточным, чтоб считать что приём данных окончен. Ежели нет достаточного аппаратного признака, тогда буду использовать таймер, который будет следить за наличием достаточной паузы неактивности работы UART после прихода последнего байта, что и будет означать о окончании передачи GPS пакета данных.
Go to the top of the page
 
+Quote Post
drum1987
сообщение Mar 12 2013, 09:48
Сообщение #5


Местный
***

Группа: Участник
Сообщений: 255
Регистрация: 3-02-09
Из: Омск
Пользователь №: 44 323



вы когда байт складываете в буфер попутно проверяйте не символ ли это переноса строки...если нет то ждете дальше, а если да, то значит вы приняли посылку полностью...можно выставить флаг или сразу обрабатывать принятые данные.
Go to the top of the page
 
+Quote Post
alexdos
сообщение Mar 12 2013, 10:06
Сообщение #6


Местный
***

Группа: Участник
Сообщений: 339
Регистрация: 10-07-08
Из: Херсон
Пользователь №: 38 856



Цитата(drum1987 @ Mar 12 2013, 12:48) *
вы когда байт складываете в буфер попутно проверяйте не символ ли это переноса строки...если нет то ждете дальше, а если да, то значит вы приняли посылку полностью...можно выставить флаг или сразу обрабатывать принятые данные.

Я уже писал, что в общем пакете данных находится несколько NMEA, каждый с которых оканчивается символом переноса строки.
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Mar 12 2013, 10:26
Сообщение #7


Профессионал
*****

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Цитата(alexdos @ Mar 12 2013, 13:06) *
Я уже писал, что в общем пакете данных находится несколько NMEA, каждый с которых оканчивается символом переноса строки.


Любая NMEA-строка начинается с $ и заканчивается \r\n. Да ещё и контрольную сумму содержит.
Сделайте как это делают везде и повсюду - разделите процесс приёма байтов по UART и складывания их в буффер FIFO и процесс извлечения байт из FIFO UART поиска ключевых символов ($ - начало строки, \r или \n - завершение строки) и последующей обработки NMEA-строк.
На форуме есть примеры организации FIFO и методы работы с ней.
Если нет желания городить FIFO, можете прямо в прерывании отлавливать ключевые символы и по ним определять начало/завершение строки и устанавливать какой-либо флаг что принята полная NMEA-строка.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 12 2013, 10:44
Сообщение #8


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (alexdos @ Mar 12 2013, 12:06) *
Я уже писал, что в общем пакете данных находится несколько NMEA, каждый с которых оканчивается символом переноса строки.
Поставьте себя на место процессора. По какому признаку вы опредлелили бы, что пакет закончился? По паузе? Так и спрашивайте - "есть ли механизм обнаружения пауз в посылке?". Специального механизма отслеживания пауз в UART нет. Да, можно городить на дополнительном таймере.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Mar 12 2013, 13:12
Сообщение #9


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Цитата(alexdos @ Mar 12 2013, 10:36) *
KnightIgor Вы бы по сути сказали, а не высказывали предположения о моих познаниях.

NMEA пакеты представляют собой "читабельные" строки, начинающиеся, как уже отвечали, c $ и заканчивающиеся символами возврата каретки и перевода строки. То есть, "классика" ASCII терминалов эры больших компьютеров 70-х - 80-х годов. GPS модуль, выдающий NMEA пакеты, выдает такие строки разного(!) содержания (различные токены) довольно интенсивно: если посмотреть на терминал, ну просто сплошным потоком! Полагаться на какие-либо паузы между пакетами не приходится: даже если они и есть, они могут быть нерегулярны или вариироваться от производителя к производителю. Вывод - разделять пакеты на основе пауз есть совершенно ненадежное дело, об этом нужно забыть.

Представьте себе три процесса: первый процесс "толкается" прерыванием от приема байта от USART и тупо записывает принятый байт в буфер FIFO.

Второй процесс выбирает побайтно из этого FIFO и тупо складывает ОТОБРАЖАЕМЫЕ символы (то есть, только те, что не меньше 0х20) в еще один линейный буфер (строку) друг за другом, пока не наткнется на символ \n. Если это произошло, процесс дополняет содержимое линейной строки конечным нулем (ASCIIZ) и передает ее копию вышестоящему процессу №3 для синтаксического разбора, а сам начинает нанизывание строки сначала.

Третий процесс получает на вход фактически строку NMEA, которую он должен разчленить на данные с помощью, например, sscanf(). Если принятая строка содержит разумные данные (см. форматы различных сообщений и контрольную сумму), процесс выполняет требуемые действия.

GPS модул выплевывает много разных токенов, содержимое которых может пересекаться. Некторые токены могут быть вообще не нужны. Например, меня интересовали в проекте только время и координаты. Я выбрал токен $GPRMC, а остальные заглушил, то есть передал в GPS модуль управляющие команды фильтрации. Кроме того, я уменьшил частоту передачи сообщений с 0.25с до 1с, т.к. мне чаще не нужно, а процессор разгружается.

Вам код дать?

Сообщение отредактировал KnightIgor - Mar 12 2013, 13:21
Go to the top of the page
 
+Quote Post
alexdos
сообщение Mar 12 2013, 13:49
Сообщение #10


Местный
***

Группа: Участник
Сообщений: 339
Регистрация: 10-07-08
Из: Херсон
Пользователь №: 38 856



Сергей Борщ , спасибо за понятный ответ.
Теперь осталось разобратся что ж за прерывание USART_IT_IDLE. Когда оно происходит.


Цитата(KnightIgor @ Mar 12 2013, 17:12) *
Вам код дать?



Спасибо за предложения кода. Но он мне не нужен. На PIC18F46J50, у меня все реализовано, и работает в сотнях устройств без нареканий. Да, я принудительно оключил ("заглушил") передачу ненужных мне данных с GPS. Да, я знаю про кольцевые буферы, про парсеры и тому подобное. Я следую логике, что приняв весь пакет от GPS за времмя приблизительно 17 милиСек (не более 200 байт) у меня будет времени разобратся с этим пакетом 1 - 0.017 = 0.983 Сек. В случае же к примеру использования методики отлавливания конца строки, и если буфер не достаточной величины (или указатель обнуляется) , мне желательно вложится в время кратное приёму одного байта, для обработки принятого NMEI, а это составляет приблизительно 86 микроСек. Вот поэтому я и хочу принять весь пакет, чтоб потом неспешно, его разобрать.

Сообщение отредактировал alexdos - Mar 12 2013, 13:51
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 12 2013, 14:05
Сообщение #11


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (alexdos @ Mar 12 2013, 15:49) *
Теперь осталось разобратся что ж за прерывание USART_IT_IDLE. Когда оно происходит.
Оно возникает если с момента последнего стопа не возникло нового старта за время 10 битовых интервалов. Вы уверены, что приемник не сделает такую паузу в середине пакета? Я бы не стал на это закладываться. Вы можете, конечно, идти своим путем. Но если в спецификации протокола сказано, что признаком конца посылки является символ перевода строки, я бы не стал придумывать какие-то еще косвенные никем не гарантированные признаки. Откуда вы взяли 86 мкс? У вас буфер. Большой. Пока вы выгребаете-разбираете из него пакет с одной стороны, прерывание складывает в него новые байты с другой. И время обработки определяется размером этого буфера. Никаких проблем. Если вы сделаете размер этого буфера таким же, как и в вашем варианте с приемом всего-всего, то и времени на обработку у вас будет не меньше, а даже больше на время передачи этого пакета сообщений - ведь пока приходит очередное сообщение в пакете вы уже можете обрабатывать предыдущее.
Но вы можете идти своим путем.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Mar 12 2013, 14:07
Сообщение #12


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Цитата(alexdos @ Mar 12 2013, 14:49) *
знаю про кольцевые буферы, про парсеры и тому подобное.

Ну так Вы все знаете. А неполно поставленный вопрос вначале наводил на иную оценку. Извините.

Цитата
Я следую логике, что приняв весь пакет от GPS за времмя приблизительно 17 милиСек (не более 200 байт) у меня будет времени разобратся с этим пакетом 1 - 0.017 = 0.983 Сек. В случае же к примеру использования методики отлавливания конца строки, и если буфер не достаточной величины (или указатель обнуляется) , мне желательно вложится в время кратное приёму одного байта, для обработки принятого NMEI, а это составляет приблизительно 86 микроСек. Вот поэтому я и хочу принять весь пакет, чтоб потом неспешно, его разобрать.

Думаю, при такой постановке вопроса и условии, что токенов мало (остальные отфильтрованы), а период составляет, скажем, 1 секунду, можно пойти по пути определения окончания пачки токенов путем таймаута. USART это вряд ли обеспечит: IDLE срабатывает, если прошло пару битов со времени последнего STOP. Никто, однако, не может гарантировать, что GPS сыплет байтами плотно друг за дружкой. Поэтому об IDLE можете тоже забыть. Остается только внешний таймер, перезапускаемый приемом байта USART и срабатывающий, скажем, после неприема трех-четырех байт - это надо заценить опытно.

Тем не менее, я не понимаю проблемы вложиться с обработкой токена в какие-то жесткие временные рамки: их просто нет, т.к. обработка токена (читай - строки) может происходить, пока принимается другой токен, а это - куча байт, а значит - и времени. То же касается и требуемой памяти: токены не такие уж и длинные (байт 50-60, думаю). Неужели напряг с этим? Вы же в форуме ARM - тут речь о множестве килобайт в микроконтроллерах или мегабайт, кто там с внешней памятью играется....
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Mar 12 2013, 16:57
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Думаю все тянется со старого пика, который работает без нареканий.

у вас есть определенное количество действий которое надо совершить с символами. Это занимает сколько-то тактов процессора. И это будет всегда занимать столько тактов (с точностью до оптимизации) не важно как вы будете их обрабатывать, сначала все сложите, а потом проверите, или будете складывать попутно проверяя.

Я так понимаю у вас есть функция монопольного парсинга строк, эта функция работает долго и вызывать ее каждый символ вы не можете. А переписать ее чтобы она был легкой и работала в несколько этапов параллельно вы не хотите.

Тогда вам надо самим определить критерий прихода всего пакета (его нет в описании протокола и остается только придумать), и реализовать. У уарта есть флаги что начался прием, и прием закончен. Можете мерить паузу между ними. Но будет ли это все дальше работать без нареканий никто вам не скажет...


П.С, Если уж быть совсем взрослыми мальчиками, то я бы подключил ДМА контроллер, который бы пихал уарт символы в буфер заведомо большей длины, так процессор вообще не тратит ресурсов на сбор сообщения. Проблема лишь в критерии когда проверять буфер...
Go to the top of the page
 
+Quote Post
alexdos
сообщение Mar 12 2013, 17:38
Сообщение #14


Местный
***

Группа: Участник
Сообщений: 339
Регистрация: 10-07-08
Из: Херсон
Пользователь №: 38 856



Цитата(Golikov A. @ Mar 12 2013, 20:57) *
П.С, Если уж быть совсем взрослыми мальчиками, то я бы подключил ДМА контроллер, который бы пихал уарт символы в буфер заведомо большей длины, так процессор вообще не тратит ресурсов на сбор сообщения. Проблема лишь в критерии когда проверять буфер...

Ну так что я в прерывании складываю, что ДМА заставлю. Упор опять же в одно "критерии когда проверять буфер". В общем тенденции я понял. И понял главное, в UART надёжного механизма определения того что данные прекратились приходить нет.
Go to the top of the page
 
+Quote Post
richie
сообщение Mar 12 2013, 18:10
Сообщение #15


Частый гость
**

Группа: Свой
Сообщений: 147
Регистрация: 5-07-04
Из: Обнинск
Пользователь №: 261



А это зависит от самих данных, соглашения об их организации.
Это в народе кличут "протоколом обмена", в котором строго оговаривается разделение данных.
Вот Вам и объясняют, что в NMEA имеет строго определенный "маркер начала" и "маркер конца".

P.S. То что разделение по времени работает на сотнях устройств c PICами, не является доказательством
правильной реализации. Есть ли в том, PIcовском, драйвере диагностика того сколько было "ошибочных" пакетов?
В чем заключается "ошибочность" пакета?
Go to the top of the page
 
+Quote Post

3 страниц V   1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 17th June 2025 - 13:50
Рейтинг@Mail.ru


Страница сгенерированна за 0.01503 секунд с 7
ELECTRONIX ©2004-2016