Прием и парсинг NMEA-данных от GPS-приемника
GPS-приемники сегодня используются в самых разных устройствах - от автомобильных трекеров до беспилотных летательных аппаратов, независимо от применения, большинство таких модулей передают информацию о положении в формате NMEA 0183, в этой статье я разберу, как принять эти данные от GPS-модуля на микроконтроллер STM32 и преобразовывать их в удобный для программы вид.
А также в статье будут рассмотрены два варианта подключения GPS-приемников к микроконтроллеру STM32:
Модуль GPS c UART-интерфейсом (TTL-уровни), подключаемый на прямую к микроконтроллеру;
Модуль GPS с интерфейсом RS-232, данные от такого типа gps, необходимо принимать через преобразователь уровней TTL.
В данном проекте используются GPS-приемники: LS23030 (UART) и LS23036(RS-232).
Схема подключения GPS-UART
Подключение модуля-GPS(UART) к микроконтроллеру STM32F103
Сигнал GPS, подключается к выводу PA10-31_контакт - RX(МК-STM32F103)
Для более стабильного напряжения питания можно использовать следующую схему, в которой работает понижающий преобразователь MP231, но необходим источник +12В, в моем случае используется аккумуляторная сборка (NiMH/Pb +12В).
Понижающий преобразователь напряжения MP2315 [ +12V до +5V ]
Вид осциллограммы передаваемых данных модуля-gps(uart) (линия TX)
Осциллограмма амплитуды данных от модуля-gps(uart)
Показатель амплитуды данных от модуля gps(uart) = delta [ 3.4V ], можно подключать к микроконтроллеру STM32.
Схема подключения GPS(RS-232)
Подключение модуля-GPS(RS-232) через ADM3202 к МК-STM32F103
Сигнал модуля-gps(rs-232), сначала приходит на 13 контакт преобразователя ADM3202, далее преобразованный сигнал (TTL) уходит на PA10-31_контакт - RX(МК-STM32F103)
Схема подключения ADM3202 к МКSTM32 - макет
Макет ADM3202 и подключение к STM32F103
Также для более стабильного напряжения питания по +5В, можно использовать схему преобразователя напряжения MP2315.
Для более стабильного напряжения питания по +3В, можно использовать следующую схему, в которой работает линейный стабилизатор напряжения LP2985.
Линейный стабилизатор напряжения LP2985 (+5В +3В)
Краткая информация о преобразователе ADM3202
Микроконтроллеры STM32, работают с логическими уровнями TTL/CMOS - обычно это 3.3В или 5В, интерфейс RS-232, напротив, использует более высокие и отрицательные напряжения ( от ±3В до ±12В), что делает их напрямую несовместимыми.
Если подключить напрямую модуль-GPS (RS-232) к выводам МК-STM32, это может не только привести к искажению данных, но и физически повредить выводы. ADM3202 решает эту задачу, переводя сигналы из одного уровня в другой, в обоих направлениях.
ADM3202 - это двухканальный приемопередатчик уровней RS-232 - TTL, выполняет сразу две задачи:
Преобразование входящих RS-232 сигналов в безопасные TTL-уровни(RX-канал);
Преобразование исходящих TTL-сигналов микроконтроллера в RS-232(TX-канал).
Для формирования требуемых амплитуд RS-232, внутри микросхемы используется помповый преобразователь напряжения(chage pump) с четырьмя внешними конденсаторами, это позволяет работать от одного источника питания (от 3В до 5.5В).
Вид осциллограммы передаваемых данных модуля-gps(rs-232) до преобразования ADM3202
Осциллограмма амплитуды данных от модуля-gps(rs-232) до преобразования ADM3202
Показатель амплитуды данных от модуля gps(rs-232) до преобразования = delta [ 10.6V ], нельзя подключать к микроконтроллеру STM32.
Вид осциллограммы передаваемых данных модуля-gps(rs-232) после преобразования ADM3202
Осциллограмма амплитуды данных от модуля-gps(rs-232) после преобразования ADM3202
Показатель амплитуды данных от модуля gps(rs-232) после преобразования = delta [ 3.6V ], можно подключать к микроконтроллеру STM32.
Настройка микроконтроллера STM32F103 в CubeIDE
Конфигурация Parametr Settings
В параметрах USART (Parametr Settings) я выбираю:
Mode: Asynchronous (асинхронный режим);
Baud Rate: 9600 бит/с (в моем примере два модуля-gps (rs-232 и uart) работают на скорости 9600).
все остальные параметры без изменений.
Настройка "Parameter settings"
Конфигурация NVIC Settings
Захожу в параметр (NVIC Settings) и включаю глобальное прерывание
Для отслеживания состояния интерфейса USART и обработки важных событий (например, завершения приема или ошибки), в разделе NVIC Settings было включено глобальное прерывание USART, это обеспечивает возможность немедленного реагирования со стороны микроконтроллера на изменения состояния периферии без постоянного опроса регистров.
Настройка "NVIC Settings"
При работе с GPS-модулями, которые передают NMEA-сообщения раз в секунду (1Hz), важно правильно организовать прием данных, чтобы не пропустить ни одного пакета. Необходимо настроить DMA в режиме Circular данный режим минимизирует нагрузку на процессор и гарантирует надежный прием.
Конфигурация DMA Settings
Захожу в параметр DMA Settings и выполняю следующие настройки:
Выбор потока/канала: USART1_RX (прием данных);
Mode: Circular ;
Increment Memory Address: Enabled (автоинкремент памяти);
Data Width: Byte (8 бит, соответствует формату NMEA).
Настройка "DMA Settings"
Реализация программного кода(настройка и прием данных)
Коротко о NMEA 0183
Это текстовый протокол, используемый для передачи данных между морским и авиационным навигационным оборудованием, включая GPS-приемники. Большинство современных GPS-модулей выводят информацию именно в этом формате.
Основные особенности:
Текстовый формат – данные передаются в виде ASCII-строк;
Структура сообщений – каждая строка начинается с $, содержит идентификатор типа данных и заканчивается контрольной суммой;
Скорость передачи – обычно 9600 бод (но может быть и выше для высокочастотных модулей);
Частота обновления – чаще всего 1 раз в секунду (1Hz), но бывают 5Hz, 10Hz и более.
Пример строки (GGA – Global Positioning System Fix Data):
После обработки GGA:
Время: 11:25:30
Широта: 60.20576° N
Долгота: 30.261315° E
Качество фикса: 1
Спутников: 10
Высота: 45.3 м
Пример строки (RMC – Recommended Minimum Navigation Information):
После обработки RMC:
Время: 11:25:30
Статус: Данные действительные
Широта: 60.20576° N
Долгота: 30.261315° E
Скорость: 5.12 узла (~9.48 км/ч)
Курс: 87.45°
Дата: 11.08.2025
Также прикрепляю еще одну ссылку, где в детальности продемонстрирована расшифровка протокола NMEA0183 [https://wiki.iarduino.ru/page/NMEA-0183/].
Определение структур данных в заголовочном файле [ NMEA.h ]
Для удобства работы с навигационной информацией из gps-приемника, здесь я заранее описываю набор структур, каждая из которых отвечает за свой логический блок данных.
Реализация модуля парсинга протокола NMEA.c
Функция decodeGGA()
Парсит строку $GPGGA и заполняет структуру GGASTRUCT данными: время, координаты, высота, количество спутников, качество фиксации.
Шаги работы функции:
Подготовка к поиску нужных данных
Переменная inx - это текущий индекс в строке GGAbuffer;
Сначала иду пропуск ненужных полей (счетчик двигается до следующей ,)
Проверка валидации качества позиционирования
В NMEA поле качества фиксации (Fix Quality) может быть:
0 - нет фикса, 1 - GPS Fix, 2-DGPS Fix, 4/5/6 другие корректные варианты;
Если поле содержит из разрешенных цифр, то в gga->isfixValid устанавливается в 1, иначе функция возвращает ошибку.
Чтение времени
Извлекается время в формате HHMMSS (UTC);
Преобразуются числа;
Корректируется по смещению GMT, при необходимости меняется день (daychange++ или daycahnge--).
Чтение широты (Latitude)
Формат в NMEA: DDMM.MMM;
Первые цифры - градусы, остальное - минуты;
Код выделяет минуты, делит их на 60 и добавляет к градусам;
Если NS == 'S', широта делается отрицательной.
Чтение долготы (Longitude)
Формат в NMEA: DDMM.MMM;
Аналогично широте, но первые 3 цифры - градусы;
Если EW == 'W', долгота делается отрицательной.
Чтение типа вычисления координат
Из поля после долготы извлекается число (gga->calc.calculation), указывающее метод позиционирования.
Чтение количества спутников
Следующее поле - количество видимых спутников (gga->numofsat).
Пропуск HDOP
HDOP (Horizontal Dilution of Precision) не используется, просто пропускается.
Чтение высоты
Поле с высотой (gga->alt.altitude) и единицами (gga->alt.unit, обычно 'M' - метры).
Завершение
Возвращается 0 при успешном разборе.
Функция decodeRMC()
Парсит строку $GPRMC и заполняет структуру RMCSTRUCT и извлекает: валидность данных, скорость, курс и дату.
Пропуск времени
Сначала идет поле времени, но в этой функции оно не сохраняется.
Проверка валидности
Если после времени идет А(Active) - данные актуальны;
Если V(Void) нет актуальных данных, функция возвращает ошибку.
Пропуск координат
Пропускаются поля широты, долготы и направления (NS/EW).
Чтение скорости
В NMEA скорость указывается в узлах;
Код переводит строку в число с плавающей точкой и записывает в rmc->speed.
Чтение курса
Следующее поле - курс (угол направления движения в градусах относительно севера).
Чтение даты
Формат: DDMMYY;
Код выделяет день, месяц, год, корректирует день с учетом daychange (из GGA), и записывает в rmc->date.
Реализация модуля обработчика потока от UART-GPS uartProc_GNSS.c
Функция uart_Handler_GNSS - это основной обработчик UART-потока, вызывается постоянно из главного цикла.
Логика работы:
Проверяет, сработали ли прерывания DMA (половина буфера или полный буфер);
Если пришли новые данные - устанавливает флаг активности GPS (gParams.isGPS = 1);
Поиск GGA или RMC
В режиме shabloneMode = 0 ищет последовательность GGA или RMC;
Когда шаблон найден, переключаемся в режим shabloneMode = 1;
В режиме 1 копирует байты до символа конца строки (13 или 10);
Действие когда собрана строка
Записывает строку в буфер buf_GGA или buf_RMC в зависимости от типа;
Обновляет время последнего получения GPS (gps_time_receive).
Декодирование
Вызывает decodeGGA() и decodeRMC() для извлечения данных в структуру gpsData.
Формирование выходного пакета:
Если хотя бы одно из сообщений валидно, формирует строку с координатами, временем, количеством спутников, режим фикса, высотой и курсом.
Записывает в результат в uart_rezult_buf_out_AB[] с преамбулой 0x5A 0xA5 и длиной пакета.
Если в течение (DELAY_GPS_STATUS_CONNECT)1000 миллисекунд новых данных нет - GPS считается отключенным (gParams.isGPS= 0).
uint8_t* dpi_getGPS_buffer (Возвращает указатель на готовый пакет данных для передачи ведущему устройству, а так же его размер).
void uart_startRecieving_GNSS (Запускает прием данных от GPS-приемника в режиме DMA).
Ссылка на скачивание исходного кода [ https://t.me/ChipCraft В закрепленном сообщении [ #исскуствомк_исходный_код -Исходный код для Module_GPS_NMEA0183]
Графический GPS-трекер я разработал для тестирования на С#, если Вам будет интересно, пишите в комментариях и я с радостью напишу статью.
Если статья показалась Вам интересной, буду рад выпустить для Вас еще множество статей исследований по всевозможным видам устройств, так что, если не хотите их пропустить – буду благодарен за подписку на мой ТГ-канал: https://t.me/ChipCraft.


















Лига Новых Технологий
2.1K постов17K подписчиков
Правила сообщества
Главное правило, это вести себя как цивилизованный человек!
Но теперь есть еще дополнительные правила!
1. Нельзя раскручивать свой сайт, любую другую соц сеть или мессенджер, указывая их как источник. Если данная разработка принадлежит вам, тогда можно.
2. Нельзя изменять заглавие или текст поста, как указано в источнике, таким образом чтобы разжигать конфликт.
3. Постите, пожалуйста, полный текст с источника, а не превью и ссылка.