Создать сайт
Приём по UART сообщений NMEA от приёмника GPS (STM32). - Форум
Среда, 18.07.2012, 20:05 Вы вошли как Гость | Группа "Гости"
Eugene's MCU
Главная | | Мой профиль | Выход | RSS

[ Личные сообщения() · Новые сообщения · Участники · Правила форума · Поиск · RSS ]

Страница 1 из 11
Форум » Основной раздел » Разработка: программирование, схемотехника. » Приём по UART сообщений NMEA от приёмника GPS (STM32).
Приём по UART сообщений NMEA от приёмника GPS (STM32).
eugenemcu

Дата: Понедельник, 04.04.2011, 18:40 | Сообщение # 1

Группа: Администраторы
Сообщений: 115
Статус: Offline
Я бы посоветовал вам сразу привыкать к определённому способу структурирования своих программ.
Удобоваримой единой теории на этот счёт нет, по крайней мере, мне такая не встречалась, но есть интересные принципы.

Самый простой, надёжный и наглядный способ это разбиение программы на процессы, задачи, называйте, как хотите, в общем, на функциональные куски и оформление каждого из них в виде т. н. конечного автомата. Например, то, о чём вы писали – приём и обработка сообщения от GPS-приёмника тоже можно выделить в отдельный процесс.

Алгоритм конечного автомата заключается в следующем:

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


[ (RU) ]

eugenemcu

Дата: Понедельник, 04.04.2011, 18:41 | Сообщение # 2

Группа: Администраторы
Сообщений: 115
Статус: Offline
Применительно к нашей теме: приём сообщений от GPS, как отдельный процесс можно разбить на следующие стадии, которые будут переключаться переменной gps-state:
1. Ожидание и приём признака начала сообщения (gps-state=1).
2. Запись последующих байтов сообщения, ожидание признака конца сообщения и установка флага «сообщение принято» (gps-state=2).
3. Проверка контрольной суммы сообщения, выделение и сохранение полезных данных. (gps-state=3).

Для реализации задачи понадобятся переменные:

Code
      
u8      gps_state=1; // Состояние автомата приёмника GPS.
// Имена состояний автомата должны быть осмысленные.
#define GPS_WAIT_HEAD 1 // Ожидание начала сообщения.
#define GPS_WAIT_TAIL 2 // Ожидание конца сообщения.
#define GPS_CHEK_MSG 3 // Проверка сообщения.

#define U1RXBUF_SIZE    128 // Размер приёмного буфера UART1.
u8      uart1_rx_buf[U1RXBUF_SIZE]; // Буфер для приёма сообщения.
u8      uart1_rx_bit; // Номер байта от GPS принимаемого в буфер.
    

Подробнее по состояниям автомата:
В обработчике приёма байта в UART:

1. Ожидание начала сообщения gps-state=1. Признак начала сообщения в протоколе NMEA – символ “$”.

Code

if (gps_state==GPS_WAIT_HEAD) // Если ждём начало сообщения.
{
    if (USART1->DR=='$')       
    {
       gps_state=GPS_WAIT_TAIL; // Записывать в буфер и ждать конца сообщения.
       uart1_rx_bit=0; // Записывать следующие байты с нулевого элемента буфера.
      _spin_m(PORTC,1<<LED4);       
    }
}     
    

Как только принимается байт "$" автомат переключается в слудующее состояние GPS_WAIT_TAIL.


[ (RU) ]

eugenemcu

Дата: Понедельник, 04.04.2011, 18:41 | Сообщение # 3

Группа: Администраторы
Сообщений: 115
Статус: Offline
2. Ожидание конца сообщения gps-state=2. Признак конца сообщения – символы CR и LF.

Code
if (gps_state==GPS_WAIT_TAIL) // Если ждём конца сообщения.
{
         if (uart1_rx_bit<U1RXBUF_SIZE) uart1_rx_buf[uart1_rx_bit]=USART1->DR; // Помещаем принятый байт в буфер.
         if ((uart1_rx_buf[uart1_rx_bit]==0x0A)&&(uart1_rx_buf[uart1_rx_bit-1]==0x0D)) // Если в буфер принят <LF> и <CR>.
         {                             
             if ((uart1_rx_buf[3]=='G')&&(uart1_rx_buf[4]=='L')&&(uart1_rx_buf[5]=='L')) {gps_state=GPS_CHEK_MSG;}  
             else {gps_state=GPS_WAIT_HEAD;} // Не "GLL"-сообщение, переключиться на приём нового сообщения.
         }
         uart1_rx_bit++; // Наращиваем счётчик байтов буфера.
}



[ (RU) ]

eugenemcu

Дата: Понедельник, 04.04.2011, 18:58 | Сообщение # 4

Группа: Администраторы
Сообщений: 115
Статус: Offline
И последнее состояние автомата с обработкой принятого сообщения нужно разместить в фоне:
Code
   
          if (gps_state==GPS_CHEK_MSG)
          {
              // Здесь обработка сообщения.
              _spin_m(PORTC,1<<LED3); // Зажечь светодиод.
              //gps_state=GPS_WAIT_HEAD; // Ждать следующее сообщение.
          }
     


Проект под IAR >> STM32_GPS_emcu_iar.rar


[ (RU) ]

burchik

Дата: Среда, 06.04.2011, 13:56 | Сообщение # 5

Группа: Пользователи
Сообщений: 5
Статус: Offline
Проблемы были с таблицей векторов которую я не подключил. Нашел файл startup_stm32f10x_md_vl.s и подцепил его.
Сейчас во время работы программы загорается LED4 как правильно его назвать - индикатор начала сообщения, происходит зацикливание в обработчике прерывания на двух условиях :
Code
if (USART3->SR&USART_SR_RXNE) // Если прерывание по приему

и
Code
if (USART3->SR&USART_SR_TC) // Если прерывание по завершению передачи

Код main.c вставить не могу ибо превышен лимит сообщения, по этому прикрепляю файлом.

Добавлено (06.04.2011, 13:56)
---------------------------------------------
Долго дебажил, и в итоге добавив вывод в терминал понял, что все работает уже давно :-)
В терминал выкидываю строку GLL. Плохо разобрался в том успею ли я распарсить и выполнить необходимые мне действия до наступления очередного прерывания. И что произойдет если не успею. Продолжаю разбираться... Премного благодарю :-)
main.c(6Kb)

[ (RU) ]

eugenemcu

Дата: Среда, 06.04.2011, 14:30 | Сообщение # 6

Группа: Администраторы
Сообщений: 115
Статус: Offline
Конечно, успеете. Ведь сообщения GLL приходят раз в секунду.
И снова переключитесь на приём от GPS (gps_state=GPS_WAIT_HEAD;) только после того как обработаете принятый буфер.
В этом надёжность и наглядность автомата - пока он занят проверкой массива (GPS_CHEK_MSG) он не может ничего принимать, так как приём возможен только в состояниях GPS_WAIT_HEAD и GPS_WAIT_TAIL.


[ (RU) ]

eugenemcu

Дата: Среда, 06.04.2011, 15:28 | Сообщение # 7

Группа: Администраторы
Сообщений: 115
Статус: Offline
Для проверки в терминале можно отправлять на 4800 кбит что-то вроде:
$GPRMC,092204.999,A,4250.5589,S,14718.5084,E,0.00,89.68,211200,,*25@#$GPGGA,092204.999,4250.5589,S,14718.5084,E,1,04,24.4,19.7,M,,,, 0000*1F@#$GPGLL,4250.5589,S,14718.5084,E,092204.999,A*2D@#
< СR >< LF > для удобства заменены на @ #
STM будет отвечать сообщением GLL. Светодиод PC8 меняет состояние на каждый “$”, PC9 на каждое сообщение GLL.

В обработчик полезно поставить USART1->SR&=~USART_SR_RXNE; // Очистить флаг "Принят байт".
Буфер увеличить до 256 байт (не такие уж короткие сообщения).

Проект:
STM32_GPS_emcu_.rar(78Kb)

[ (RU) ]

burchik

Дата: Среда, 06.04.2011, 19:02 | Сообщение # 8

Группа: Пользователи
Сообщений: 5
Статус: Offline
Не сразу догадался говорить ему NMEAвским языком в терминал.
Запарсил нужную строку. Парс правда сделал просто побитовый сверхпростой. Теперь попытаюсь прикрутить ноунеймовский LCD дисплей 2x16, очень похожий на тот что из статьи. (Выдрал из дохлого систмного телефона)
На данном этапе получаю широту-долготу двумя отформатированными строками в терминале. Большое спасибо за поддержку :-)


[ (RU) ]

burchik

Дата: Пятница, 08.04.2011, 10:47 | Сообщение # 9

Группа: Пользователи
Сообщений: 5
Статус: Offline
Получил в итоге вот такой девайс.

С программой еще есть куда разбираться, но это уже детали...
Благодарю еще раз за великую помощь и поддержку, Евгений.
2266138.jpg(40Kb)

[ (RU) ]

Форум » Основной раздел » Разработка: программирование, схемотехника. » Приём по UART сообщений NMEA от приёмника GPS (STM32).
Страница 1 из 11
Поиск: