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, внутри микросхемы используется помповый преобразователь напряжения(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) я выбираю:
все остальные параметры без изменений.
Настройка "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).
Реализация программного кода(настройка и прием данных)
Это текстовый протокол, используемый для передачи данных между морским и авиационным навигационным оборудованием, включая GPS-приемники. Большинство современных GPS-модулей выводят информацию именно в этом формате.
Текстовый формат – данные передаются в виде ASCII-строк;
Структура сообщений – каждая строка начинается с $, содержит идентификатор типа данных и заканчивается контрольной суммой;
Скорость передачи – обычно 9600 бод (но может быть и выше для высокочастотных модулей);
Частота обновления – чаще всего 1 раз в секунду (1Hz), но бывают 5Hz, 10Hz и более.
Пример строки (GGA – Global Positioning System Fix Data):
Время: 11:25:30
Широта: 60.20576° N
Долгота: 30.261315° E
Качество фикса: 1
Спутников: 10
Высота: 45.3 м
Пример строки (RMC – Recommended Minimum Navigation Information):
Также прикрепляю еще одну ссылку, где в детальности продемонстрирована расшифровка протокола NMEA0183 [https://wiki.iarduino.ru/page/NMEA-0183/].
Определение структур данных в заголовочном файле [ NMEA.h ]
Для удобства работы с навигационной информацией из gps-приемника, здесь я заранее описываю набор структур, каждая из которых отвечает за свой логический блок данных.
Реализация модуля парсинга протокола NMEA.c
Парсит строку $GPGGA и заполняет структуру GGASTRUCT данными: время, координаты, высота, количество спутников, качество фиксации.
Подготовка к поиску нужных данных
Переменная inx - это текущий индекс в строке GGAbuffer;
Сначала иду пропуск ненужных полей (счетчик двигается до следующей ,)
Проверка валидации качества позиционирования
Чтение времени
Извлекается время в формате HHMMSS (UTC);
Преобразуются числа;
Корректируется по смещению GMT, при необходимости меняется день (daychange++ или daycahnge--).
Чтение широты (Latitude)
Формат в NMEA: DDMM.MMM;
Первые цифры - градусы, остальное - минуты;
Код выделяет минуты, делит их на 60 и добавляет к градусам;
Если NS == 'S', широта делается отрицательной.
Чтение долготы (Longitude)
Формат в NMEA: DDMM.MMM;
Аналогично широте, но первые 3 цифры - градусы;
Если EW == 'W', долгота делается отрицательной.
Чтение типа вычисления координат
Чтение количества спутников
Пропуск HDOP
Чтение высоты
Завершение
Парсит строку $GPRMC и заполняет структуру RMCSTRUCT и извлекает: валидность данных, скорость, курс и дату.
Пропуск времени
Проверка валидности
Если после времени идет А(Active) - данные актуальны;
Если V(Void) нет актуальных данных, функция возвращает ошибку.
Пропуск координат
Чтение скорости
Чтение курса
Чтение даты
Формат: 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);
Действие когда собрана строка
Декодирование
Формирование выходного пакета:
Если хотя бы одно из сообщений валидно, формирует строку с координатами, временем, количеством спутников, режим фикса, высотой и курсом.
Записывает в результат в 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.