В данной статье будет рассматриваться разработка коммутатора, для приема, обработки и передачи потока данных от GNSS-приемника и энкодера, осуществляться передача ведущему устройству будет по интерфейсу RS-485.
Интерфейс RS-485 - представляет собой промышленный стандарт физического уровня передачи данных, широко применяемый в распределенных системах управления, телеметрии и автоматизации, его ключевая особенность - использование дифференциального сигнала, что обеспечивает высокую помехоустойчивость и надежность передачи данных на значительные расстояния (до 1200 метров).
Исходный сигнал разделяется на два синхронных сигнала, передаются они по двум проводникам - линия А и линия В образующих витую пару.
На линии А передается исходный сигнал, а на линии B формируется инверсное отражение, в приемной части установлен дифференциальный усилитель, который вычисляет разность потенциалов между линиями:
- Если разность положительная (+200 мВ) - логический 0;
- Если разность отрицательная (-200 мВ) - логическая 1.
Такой метод передачи данных позволяет минимизировать влияние электромагнитных помех, так как внешние наводки одинаково взаимодействуют на обе линии и компенсируются при дифференциальном приеме.
В стандартных трансиверах интерфейса RS-485 передатчик и приемник интегрированы в одном корпусе и подключены к общей двухпроводной линии, направление выбирается выводом микроконтроллера, уровень на которой определяет в каком режиме микросхема, в приеме или в передаче.
Подробную информацию по теме интерфейса RS-485, можно изучить вот здесь [https://easyelectronics.ru/interfejs-rs-485.html].
Верхняя схема соединения устройств
Принцип взаимодействия устройств
Данная схема реализует архитектуру «ведущий-ведомый» (Master-Slave). Процесс взаимодействия можно разделить на два ключевых этапа:
- Этап опроса и обнаружения устройствПри инициализации системы ведущее устройство отправляет ведомому устройству (коммутатору) запрос на получение списка активных подключенных устройств. В данном примере запрашивается статус энкодера и приемника GNSS.Ведомое устройство, формирует и возвращает ведущему буфер данных, содержащий информацию о наличии активности или отсутствии связи с каждым из опрошенных устройств.
- Этап сбора данныхПосле успешного обнаружения активных устройств ведущее устройство инициирует цикл опроса для сбора данных. Последовательно отправляются запросы на получение данных: дистанциис энкодера и навигационной информациис приемника GNSS.Ведомое устройство агрегирует запрашиваемые параметры, формирует пакет данных и передает его ведущему устройству для последующей обработки.
Таким образом, коммутатор в данной системе обеспечивает централизованный сбор и передачу данных от периферийных устройств к управляющему ведущему устройству по запросу.
В данной схеме используется GNSS-приемник работающий по RS-232, коммутатор будет принимать данные от GNSS приемника, собирать их в пакет и отправлять ведущему устройству по RS-485.
Для взаимодействия приема и передачи данных, коммутатор и ведущее устройство работают по внутреннему протоколу по аналогии MODBUS ASCII - являющийся одним из вариантов широко распространенного промышленного протокола Modbus, предназначаемого для организации обмена между ведущим и ведомым устройствами по последовательным линиям связи (RS-232/RS-422/RS-485).
Минимальный пример формата кадра MODBUS ASCII
- Символ начала сообщения - ( : );
- Адрес устройства - указывает, какому устройству предназначен кадр;
- Код функции - определяет тип выполняемой операции (чтение, запись, диагностика);
- Данные - содержат полезную нагрузку (адреса регистров, значения, количество слов);
- Контрольная сумма - обеспечивает контроль целостности передачи данных;
- Символы конца строки - (\r\n) - фиксация завершения кадра.
Подробную информацию на тему протокола Modbus, можно изучить вот здесь [https://habr.com/ru/articles/682292/], [https://habr.com/ru/articles/281430/].
Реализация протокола связи по RS-485, описывающая форматы пакетов для приема и передачи данных между ведущим и ведомым устройством.
Краткое объяснение пакетов:
Ведущее устройство (Master) формирует и отправляет запрос:
0xAB, 0xBA, <длина команды>, 0x09, <тип энкодера>, <тип GNSS>, <режим GNSS>, '>'
Этот пакет служит командой опроса статуса:
- Байты 0xAB и 0xBA образуют преамбулу, по которой ведомое устройство синхронизирует начало кадра;
- Поле «Длина команды» содержит длину в байтах начиная с поля 4 и заканчивая полем с символом 0x3E (‘>’) включительно.
- Байт 0x09 - является кодом команды (в данном примере, запрос статуса);
- Поля <тип энкодера>, <тип GNSS> задают конфигурацию активных модулей;
- Символ '>' (0x3E)обозначает конец пакета.
Ведомое устройство (Slave) приняв пакет, формирует ответ:
0x5A, 0xA5, <длина команды>, 0x09, <установленный энкодер>, <установленный GNSS>, <тип GNSS>, '>' Здесь преамбула от ведомого устройства будет такая 0x5A, 0xA5.
Если параметр команды «Установка активного экодера» равен 1 и энкодер физически не подключен, то значение текущего типа энкодера «Установленный энкодер» становится равным -1.
Если в ответе на команду[9] параметр «Установленный GNSS » равен -1, значит GNSS не подключен, если 1 – то подключен.
Тип GNSS: 1 – одиночный режим, 4 – режим с дифференциальной коррекцией, 5 – режим дифференциальной коррекции с плавающим решением.
Перечень компонентов
Объяснение по схеме
DD2 Микроконтроллер STM32F030CCT6 выполняет функции центрального управляющего узла коммутатора данных.
Характеристики МК
- Ядро: ARM Cortex-M0, тактовая частота до 48 МГц;
- Память: 256 КБ Flash для хранения ПО, 32 КБ SRAM для оперативных данных;
- Периферия:6 универсальных синхронно-асинхронных приемопередатчиков (UART);Интерфейсы: I2C, SPI;12-битный АЦП (16 каналов);таймеры общего назначения и ШИМ-модули;системные таймеры (SysTick, watchdog).
Ссылка на техническую документацию МК [https://static.chipdip.ru/lib/915/DOC012915875.pdf]
В микроконтроллере будет задействовано сразу 3 UART-порта:
- UART_1 - предназначен для работы с GNSS-приемником;
- UART_2 - предназначен для работы с энкодером;
- UART_3 - предназначен для работы с ведущим устройством.
Выводы NRST и BOOT0
Вывод NRST(reset) используется для аппаратного сброса МК, подключается через резистор R16(10кОм) к питанию +3В — подтягивает NRST к логической «1», конденсатор С19(0,1мкФ), формирует RC-цепочку, используется для подавления помех и автосброса при включении питания, данный пример схемы гарантирует корректный старт МК после подачи питания, защищает от ложных срабатываний при скачках напряжения.
Вывод BOOT0 определяет, откуда МК будет загружать программу после сброса:
- BOOT0 = 0 — загрузка из Flash‑памяти(основной режим работы);
- BOOT0 = 1 — загрузка из системной памяти (встроенный загрузчик через UART, I2C, SPI).
В схеме вывод подтянут резистором R13(10кОм) к земле (логический «0»), это обеспечивает автоматическую загрузку программы из flash‑памяти после старта, если потребуется использовать встроенный загрузчик, можно временно подать «1» на BOOT0.
Обвязка питания VCC и VA
МК имеет несколько выводов питания:
- VCC — основное цифровое питание (3.3В);
- VA — питание аналоговой части (АЦП, компараторы и т. д.).
На выводах VCC и VA уставлен конденсатор С18 (0.1мкФ), он фильтрует высокочастотные помехи, возникающие при переключении логики, конденсатор ставиться как можно ближе к выводам МК, также дополнительно установлен танталовый конденсатор С20 (4.7мкФ), он сглаживает низкочастотные колебания и стабилизирует питание аналоговой части.
Узел кварцевого резонатора BQ
Кварцевый резонатор подключается к выводам МК (5 и 6), также добавляются нагрузочные конденсаторы С13 и С14 (12пФ), они обеспечивают корректный запуск и устойчивую работу генератора, формируя необходимую нагрузочную емкость.
После подачи напр.питания МК запускает внутренний RC-генератор, но при активации внешнего кварцевого генератора на выводах (5 и 6) начинает работать схема усилителя с положительной обратной связью, при которой:
- Кварцевый резонатор задает стабильную резонансную частоту колебаний;
- Нагрузочные конденсаторы формируют требуемую емкость, обеспечивая корректное возбуждение и работу генератора;
- Полученная частота передается во внутреннюю систему тактирования МК.
Узел RS-485
В данной схеме я использую MAX14841 - это дифференциальный трансивер RS-485/RS-422, предназначенный для передачи данных в промышленных и встраиваемых системах, техническая документация [https://www.alldatasheet.com/datasheet-pdf/pdf/332495/MAXIM/MAX14841EASA%2B.html].
На выводы 6(А) и 7(В) микросхемы DA3, поступают данные от энкодера, выводы подключены через согласующие резисторы:
- Резистор R5(120 Ом) - предотвращает отражение сигналов в линии;
- Резисторы R3 и R6(1,5 кОм) - подтягивающие, обеспечивающие корректное определение логических уровней на линии.
Резисторы R11 и R12(10 кОм) - устанавливают стабильный логический уровень на управляющих выводах RE и DE, таким образом они предотвращают ложные переключения при старте системы.
Подключение выводов к МК:
- RO(выход приемника) - подключается к PA3;
- DI(вход) - подключается к PA2;
- DE и RE - подключаются PA1;
- выводы А и B - подключаются к энкодеру.
Микросхема DA4, используется для приема и передачи данных ведущему устройству, схема подключения резисторов точно такая же как и у DA3,
Подключение выводов к МК:
- RO(выход приемника) - подключается к PB11;
- DI(вход) - подключается к PB10;
- DE и RE - подключаются PB1.
- выводы А и B - подключаются к ведущему устройству.
Узел подключения GNSS-приемника
Микроконтроллеры 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В), резистор R1 - 0 Ом работает в виде перемычки, я его добавил чтобы плата управления могла работать с разными GNSS-приемниками, приемник в данной статье работает исключительно по RS-232, но у меня есть приемники и по UART, когда мне необходимо будет исполнение платы которая должна работать с приемником UART я просто не произвожу монтаж ADM3202, ставлю резистор и все, на данный момент резистора нет, по факту разъем у меня один, я лишь только меняю компоненты в плате и все, таким образом у платы появляется несколько исполнений по монтажу.
Техническая документация ADM3202 [https://www.alldatasheet.com/datasheet-pdf/pdf/48731/AD/ADM3202.html]
Вид осциллограммы передаваемых данных модуля-gnss(rs-232) до преобразования ADM3202
Показатель амплитуды данных от модуля gps(rs-232) до преобразования = delta [ 10.6V ], нельзя подключать к микроконтроллеру STM32.
Вид осциллограммы передаваемых данных модуля-gnss(rs-232) после преобразования ADM3202
Показатель амплитуды данных от модуля gnss(rs-232) после преобразования = delta [ 3.6V ], можно подключать к микроконтроллеру STM32.
Узел преобразователя и стабилизатора напряжения
Микросхема DA1 - MP2315 представляет собой синхронный понижающий DC-DC преобразователь с интегрированными силовыми MOSFET-ключами. Высокая частота переключения (до 2.2 МГц), компактный корпус и широкий диапазон входных напряжений (от 4.5 В до 24 В), ссылка на техническую документацию MP2315 [https://www.alldatasheet.com/datasheet-pdf/pdf/1035056/MPS/MP2315.html].
Микросхема DA2 — LP2985 представляет собой малошумящий стабилизатор, предназначен для преобразования входного напряжения +5В в стабильное напряжение +3В, используемое МК и периферийными узлами, ссылка на техническую документацию LP2985 [https://www.alldatasheet.com/datasheet-pdf/pdf/99706/TI/LP2985.html].
Модель печатной платы коммутатора
Слой TOP (верхний слой) и слой BOTTOM(нижний слой) подключены к GND
Прикладываю схему и модель печатной платы cсылка на скачивание Commutator_STM32(.sch/.pcb) [ https://t.me/ChipCraft В закрепленном сообщении [ #исскуствомк_Схема_Commutator_STM32]
Прикладываю также программу для открытия P-CAD Viewer, да... она очень и очень древняя, но я данную программу по построению схем и печатных плат полюбил очень давно, и в основном проектирую только в ней, cсылка на скачивание P-CAD Viewer [ https://t.me/ChipCraft В закрепленном сообщении [ #исскуствомк_проектирование_sch/pcb — Программа для просмотра схем и печатных плат]
Краткая инструкция по открытию файлов
Для того чтобы открыть схему, необходимо открыть программу SCHView(располагается в папке P-CAD 2006 Viewer) и в ней уже открыть файл, для того чтобы открыть печатную плату, необходимо открыть программу PCBView и в ней уже открыть файл.
Настройка микроконтроллера STM32F030CCTx в CubeIDE (Ведомое устройство)
Настройка RCC и SYS (в RCC выбираю Crystal/Ceramic Resonator, так как у меня внешний кварц)
Настройка выводов узла подключения энкодера
Вывод PA1 предназначен для управления DA3 (MAX14841), он подключен к DE и RE, для приема и передачи данных энкодера, необходимо поднимать и опускать вывод МК, работа схемы:
- На выводе МК = 1 (высокий уровень, "поднят"):DE = 1 — драйвер включен (выходы A и B активны и передают данные из DI).RE = 1 — приемник выключен (выход RO отключен). Микросхема находится в режиме передачи.
- На выводе МК = 0 (низкий уровень, "опущен"):DE = 0 — драйвер выключен (выходы A и B в высокоимпедансном состоянии).RE = 0 — приемник включен (данные с A и B передаются на RO).Микросхема находится в режиме приема.
Настройка USART2
Энкодер передает данные на скорости [230400], в Baud Rate выставляю скорость, остальные параметры без изменений
Заходим во вкладку NVIC Settings и включаем прерывания
Заходим во вкладку DMA Settings и подключаем DMA
Настройка выводов узла приема и передачи данных с ведущим устройством
Вывод PB1 предназначен для управления DA4 (MAX14841), он подключен к DE и RE, для приема и передачи данных с ведущим устройством, необходимо поднимать и опускать вывод МК, работа схемы:
- На выводе МК = 1 (высокий уровень, "поднят"):DE = 1 — драйвер включен (выходы A и B активны и передают данные из DI).RE = 1 — приемник выключен (выход RO отключен). Микросхема находится в режиме передачи.
- На выводе МК = 0 (низкий уровень, "опущен"):DE = 0 — драйвер выключен (выходы A и B в высокоимпедансном состоянии).RE = 0 — приемник включен (данные с A и B передаются на RO).Микросхема находится в режиме приема.
Настройка USART3
Ведущее устройство передает и принимает данные на скорости [230400], в Baud Rate выставляю скорость, остальные параметры без изменений
Заходим во вкладку NVIC Settings и включаем прерывания
Заходим во вкладку DMA Settings и подключаем DMA
Настройка выводов узла подключения приемника-gnss
Конфигурация Parametr Settings
В параметрах USART1 (Parametr Settings) я выбираю:
- Mode: Asynchronous (асинхронный режим);
- Baud Rate: 9600 бит/с (в моем примере два модуля-gnss (rs-232 и uart) работают на скорости 9600).
все остальные параметры без изменений.
Конфигурация NVIC Settings
Захожу в параметр (NVIC Settings) и включаю глобальное прерывание
Для отслеживания состояния интерфейса USART и обработки важных событий (например, завершения приема или ошибки), в разделе NVIC Settings было включено глобальное прерывание USART, это обеспечивает возможность немедленного реагирования со стороны микроконтроллера на изменения состояния периферии без постоянного опроса регистров.
При работе с GPS-модулями, которые передают NMEA-сообщения раз в секунду (1Hz), важно правильно организовать прием данных, чтобы не пропустить ни одного пакета. Необходимо настроить DMA в режиме Circular данный режим минимизирует нагрузку на процессор и гарантирует надежный прием.
Конфигурация DMA Settings
Захожу в параметр DMA Settings и выполняю следующие настройки:
- Выбор потока/канала: USART1_RX (прием данных);
- Mode: Circular;
- Increment Memory Address: Enabled (автоинкремент памяти);
- Data Width: Byte (8 бит, соответствует формату NMEA).
Коротко о 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/].
Программная реализация ведомого устройства
Ссылка на скачивание исходного кода [ #исскуствомк_исходный_код — Исходный код для STM32F030CCTx_Switch_GPS_DP].
Модуль uart_processing.c
Данный модуль реализует обработку обмена по трем интерфейсам UART, используемым в составе коммутатора:
- UART1 - прием данных от GNSS-приемника;
- UART2 - взаимодействие с датчиками перемещения(ДПИ, ДП32, Encoder);
- UART3 - взаимодействие с ведущим устройством.
Функция void fillBuff_com9(int8_t typeDP)
Формирует ответ на девятую команду протокола, которая служит для запроса или установки типа подключенного датчика перемещения
Режим запроса статуса (typeDP == 1), возвращается текущее значение параметра gParams.type_DP которое отражает активный тип подключенного датчика.
Режим смены конфигурации (typeDP != 1) проверяется, отличается ли новый тип от ранее установленного (gParams.typeDP_fromAB), если произошла смена конфигурации, выполняются переинициализация датчиков.
После выполнения логики, функция формирует ответный пакет в буфере uart_rx_buf_com9:
- преамбула (0x5A, 0xA5);
- идентификатор команды (0x09);
- Тип ДП(retDP);
- признак активности GPS (gParams.isGPS);
- статус RTK (isRTK_GPS);
- конец сообщения (>).
Функция uart_Handler()
Это центральный узел, который предназначается для взаимодействия с ведущим устройством
Логика работы:
Анализ приема:
- Проверяется флаг uartRxABDone, сообщающий о завершении приема пакета по интерфейсу USART3;
- Валидность пакета подтверждается преамбулой (0xAB и 0xBA) и соответствием длины данных (uart_rx_buf_AB[2]).
Декодирование команды:
в зависимости от байта команды uart_rx_buf_AB[3] выполняется одна из ветвей:
- 'G' (GNSS-данные) - вызывается dpi_getGPS_buffer(), возвращает GNSS буфер и передается ведущему устройству;
- 0x09(девятая команда) - вызывается fillBuff_com9() и передается ведущему устройству;
- 'Y' (данные от датчиков перемещения) - вызывается dpi_getDP_buffer(), формирует буфер дистанции и передается ведущему устройству;
- 0x02 (версия прошивки) - формируется ответ в формате Vx.x.x> и передается ведущему устройству.
Обработка завершения передачи:
- Если пакет подготовлен, управление передается функции uart_transmitAB();
- В противном случае запускается повторный прием (uart_startRecievingAB), гарантирует непрерывность работы, после успешной отправки пакета, сбрасывается флаг uartTxIRDone_AB, восстанавливается линия приема и освобождается RS-485 (сброс сигнала DE_RE).
Модуль uart_Proc_dp.c
Краткое описание функций:
- dpi_getDp_buffer() - получение актуального пакета для передачи;
- dpi_getDist() - узнать накопленное расстояние;
- dpi_resetDist() - сбросить счетчик дистанции и внутренние буферы;
- dpi_getDpi_connect_status() - определение состояния подключения.
Данный модуль предназначен для работы с несколькими типами датчиков перемещения
ДПИ (по интерфейсу RS-485)
- Команда 0xBA 0xDC используется для запроса дистанции;
- Ответ от ДПИ передается в 6-байтном формате: 4 байта дистанции + 2 байта контрольной суммы CRC.
- Функция uartHandlerDp анализирует входящий пакет;
- CRC вычисляется по алгоритму побайтового суммирования с инверсией результата;
- Если CRC корректна, обновляется переменная dist, в которой хранится расстояние в импульсах;
- Результат упаковывается в буфер uart_rx_buf_dpi[];
- dpi_time_send и dpi_time_status_connect задают цикличность запросов и ограничение времени ожидания;
- Если ответа нет более 100мс, датчик считается отключенным (gParams.typeDP=-1).
ДП32(работа по генерации импульсов)
подключается напрямую к линии RX микроконтроллера и генерирует импульсы
- Прерывание по фронту PB3 фиксирует факт прихода импульса;
- Таймер TIM6 используется для определения направления перемещения2 импульса - > движение назад (счетчик уменьшается)
3 импульса - > движение вперед (счетчик увеличивается)
Настройка PB3 и TIM6 в CubeMX
Encoder (данный тип датчика выдает только импульсы в одном направлении, т.е. дистанция будет всегда положительная)
Каждый фронт на входе PB3 увеличивает счетчик dpEnc_counter, обновление также транслируется с преамбулой (0x5A и 0xA5).
Реализацию программного модуля работы с GNSS я уже рассказывал в этой статье [https://habr.com/ru/articles/936028/]
Главный модуль proj_main.c
Инициализационный блок
- Задержка старта (HAL_Delay(1)), обеспечивает корректность вызова системного таймера, предотвращая возможное чтение нулевого значения;
- Инициализация параметров (setDefaultParams()), формируются стандартные настройки модуля, включая все протоколы обмена и параметры периферийных интерфейсов;
- Перезапуск USART2, сначала деинициализирую и потом инициализирую, помогает корректно работать RS-485 перед началом работы;
- Инициализация функций:uart_GNSS_init() - подготавливает буферы и структуры для приема данных от GNSS -приемника;uart_Proc_dp_init() - настройка логики обработки данных от датчиков перемещения.Старт обмена данными:uart_startRecieving_DP() - запуск приема от датчиков;uart_startTransmiting_DP() - формирование и отправка первого запроса к датчику;uart_startRecieving_AB() - начало приема пакетов от ведущего устройства;uart_startRecieving_GNSS() - включение приема от GNSS-приемника.
Основной цикл работы
Внутренний цикл wihle(1) реализует вызов трех основных обработчиков:
- uart_Handler() - обеспечивает обмен с ведущим устройством по RS-485
- uart_Handler_GNSS() - выполняет разбор входящего навигационного потока в формате NMEA, а также контроль активности GNSS-приемника;
- uart_Handler_DP() - реализует обработку данных с датчиков перемещения.
Просмотр работы приема и передачи данных между ведущим и ведомым устройством, через терминал
С помощью преобразователя USB/RS-485 подключаюсь к DA4 и тестирую
Если статья показалась Вам интересной, буду рад выпустить для Вас еще множество статей исследований по всевозможным видам устройств, так что, если не хотите их пропустить — буду благодарен за подписку на мой ТГ-канал.