Uart debug что это

Отладка микроконтроллеров ARM Cortex-M по UART

Введение

Знали ли вы что ядра ARM Cortex-M в микроконтроллерах могут отлаживать сами себя?
Оказывается могут.

Читая Technical Reference Manual на ядро Cortex M3 обнаружил что у него есть прерывание DebugMon. Далее проанализировал все регистры с ним связанные. В итоге выяснил что МК может попадать в это прерывание при условии равенства регистра PC и одного из регистров FP_COMP.
Это означает что мы можем устанавливать точки останова в отлаживаемой прошивке. Так-же можно принудительно вызывать прерывание DebugMon установив бит MON_PEND регистра DEMCR в 1.

Проверка теории

Так как данные регистры присутствуют во всём семействе ядер ARM Cortex-M, возьмем первую попавшуюся отладочную плату. У меня это оказалось stm32f723e-disco. Для того чтобы не тратить время на написание инициализационного кода периферии, используем CubeMX
Из периферии нам понадобится лишь UART6, соединенный с ST-Link’ом и светодиод на плате:

Uart debug что это. Смотреть фото Uart debug что это. Смотреть картинку Uart debug что это. Картинка про Uart debug что это. Фото Uart debug что это

Генерируем проект и сразу открываем его IDE.

Для того чтобы не запутаться в регистрах связанных с отладкой, сразу введем для них определения в коде:

Для проверки что наш проект в принципе работает, пишем код, мигающий светодиодом:

Светодиод успешно заморгал, значит проект успешно компилируется и запускается.

Добавляем в этот цикл строчку:

Эта ассемблерная вставка является программной точкой останова. Теперь при отладке через ST-Link программа всегда будет останавливаться на этой строчке. Выходим из Debug в IDE и светодиод начинает моргать как и раньше.

Но что нам это дало?

А то что мы можем отлавливать точку останова прерыванием DebugMon.

Пишем его обработчик:

Компилируем, прошиваем и ничего не изменилось. Чтобы разрешить работу прерывания DebugMon, нужно поднять бит MON_EN в регистре DEMCR.

Теперь при отладке через ST-Link программа будет останавливаться как и раньше на этой строчке. Как только мы выйдем из режима отладки, в терминале начнут появляться восклицательные знаки:

Uart debug что это. Смотреть фото Uart debug что это. Смотреть картинку Uart debug что это. Картинка про Uart debug что это. Фото Uart debug что это

Далее проверяем тоже самое с регистром FP_COMP.

Находим адрес любой инструкции в цикле функции main средствами IDE и активируем точку останова:

При отключенном аппаратном отладчике, микроконтроллер тоже попадает в прерывание DebugMon.

Как это можно использовать

С помощью вышеприведенных регистров и прерывания DebugMon возможно реализовать отладку микроконтроллера без SWD/JTAG отладчика. Так-же становится возможным отлаживать прошивку устройства, с которым есть связь, но доступ к выводам SWD затруднен.

Источник

UART – Последовательный интерфейс передачи данных

Uart debug что это. Смотреть фото Uart debug что это. Смотреть картинку Uart debug что это. Картинка про Uart debug что это. Фото Uart debug что это

В сегодняшней статье мы с вами разберемся с последовательным интерфейсом UART, узнаем его плюсы и минусы, а также научимся отлаживать программу с помощью Arduino IDE без применения программаторов. Вас заинтересовало? Тогда читайте дальше!

Серьёзные среды разработки, типа IAR или ATMEL Studio, как правило, содержат в себе либо программный симулятор целевого микроконтроллера, либо имеют программные средства для работы с аппаратными отладчиками.

Среда Arduino IDE не имеет ни того, ни другого, что значительно усложняет поиск ошибок в программе. Компилятор выявляет только синтаксические ошибки, наряду с которыми существуют еще и логические (написано-то правильно, только не то делает), не говоря уж о подсчёте различных коэффициентов… Программы не пишутся без ошибок!

Существует множество методов отладки, но практически для всех необходимо физическое соединение с компьютером. Все платы Arduino (кроме Pro и Pro Mini) имеют «на борту» USB-разъём и специальную микросхему, которая преобразует интерфейс UART в USB. Так не будем же придумывать ничего лишнего и сделаем простейшую отладку с помощью интерфейса, который у нас уже есть!

Среда разработки Arduino IDE уже имеет в своём составе монитор последовательного порта, который позволяет просматривать данные, проходящие через порт, а также отправить свои данные. Таким образом, мы всегда можем передать данные из нашего устройства прямо в компьютер и вывести на экран.

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

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

UART интерфейс — описание

UART в переводе с английского звучит как “Универсальный Асинхронный Приёмопередатчик”. Существует ещё его синхронная версия с дополнительной линией тактового сигнала, но она не интересна нам в рамках статьи.

Uart debug что это. Смотреть фото Uart debug что это. Смотреть картинку Uart debug что это. Картинка про Uart debug что это. Фото Uart debug что это

Каждый бит каждого байта передаётся в равный отведённый промежуток времени (фактически, тайм-слот). Стандартным размером данных в посылке является 8 байт, но помимо данных каждый пакет несёт и служебную информацию, а именно:

Кратко параметры передаваемого сигнала записываются так:

[кол-во бит данных] [тип чётности] [кол-во стоп-битов], то есть запись 8N1 характеризует сигнал с 8 битами данных, без бита чётности (N – Not) с 1 стоп-битом.

Так как интерфейс асинхронный, то большую значимость имеет скорость передачи данных – и у приёмника, и у передатчика она должна быть одинаковой.

Скорость измеряется в битах в секунду, или коротко – в бодах. Стандарт RS232 подразумевает скорости от 1200 до 115200 бод, хотя по факту существуют скорости и ниже, и выше, причём до десятков мегабод!

Разумеется, точность везде относительна и скорость никогда не будет равняться 9600 бодам с точностью до единиц. Стандарт предусматривает возможную ошибку в скорости до 5% (не более 3% для уверенного приёма).

Далее сведены основные сведения о сигнале:

4800, 9600, 19200, 38400, 57600, 115200 бод.

Скорость передачи (бод)Время передачи одного бита (мкс)Время передачи байта (мкс)
48002082083
96001041042
1920052521
3840026260
5760017174
1152008,787

UART может быть запущен как в полудуплексном (только приём или только передача) режиме, так и в полнодуплексном режиме, так как линии приёма и передачи разделены. Линия TXD отвечает за передачу, RXD – за приём, соответственно, линии от приёмника к передатчику перекрещиваются (TX-RX, RX-TX).

Реализация UART в Arduino

Все платы Arduino, построенные на основе оригинальных, имеют минимум один интерфейс UART, продвинутые же платы, типа Arduino Mega 2560 Или Arduino Due, имею сразу 4 аппаратных интерфейса! Они не загружают контроллер, так как они отделены от ядра; всё, что необходимо – это сконфигурировать порт и запихать данные в буфер, после чего операции передачи пойдут независимо от вас.

Конечно, существуют и программные реализации UART, но они нагружают процессор. В любом случае, лучше использовать сначала аппаратные интерфейсы, а потом уже начинать придумывать что-то программное.

Контроллеры Arduino используют логические уровни такие же, каким является питание, то есть для самой популярной платы Arduino UNO уровни будут равны – ноль = 0В, 1 = 5В.

Выводы подключены к преобразователю интерфейсов через резисторы с сопротивлением 1 КОм, а к гребёнкам по бокам платы – напрямую, поэтому сигналы с гребёнок будут иметь больший приоритет. Периодически это мешает прошивать платы с подключенным датчиком по UART, так как для прошивки тоже используется UART.

Микросхема преобразователя интерфейсов не делает из себя ещё один COM-интерфейс для компьютера, она лишь эмулирует его. Несмотря на это, все программы, которые работают с COM-портом посредством Windows API (Win32 API), не отличат порт от физического порта компьютера.

Класс Serial – RS232 в лучших традициях Arduino

Uart debug что это. Смотреть фото Uart debug что это. Смотреть картинку Uart debug что это. Картинка про Uart debug что это. Фото Uart debug что это

Для удобной работы с последовательным портом разработчики Arduino написали целую библиотеку, которая значительно упрощает работу с портом, абстрагируя конечного пользователя от простой, «железной» работы с регистрами. Класс имеет множество функций, которые будут рассмотрены нами далее. Но сначала надо понять, как же компьютер примет и обработает, а точнее покажет то, что мы ему передали.

Всё дело в том, что каждый символ раскладки клавиатуры – это тоже байт. И если просто взять и отправить в порт число 65, он не выведет две цифры 6 и 5, а выведет заглавную латинскую букву А. Почему так? Потому что в таблице кодировки буква А имеет код 65. Класс позволяет выбрать между текстовым и бинарным методом передачи данных, то есть мы сможем отправить число 65 и как букву, и как число.

Источник

Uart debug что это

В статье рассказывается, как быстро встроить в firmware AVR отладочный вывод на текстовую консоль терминала.

Uart debug что это. Смотреть фото Uart debug что это. Смотреть картинку Uart debug что это. Картинка про Uart debug что это. Фото Uart debug что это

[Использование модуля oddebug.c для отладки]

1. Скачайте библиотеку V-USB [1].

2. В папке vusb-20120109\usbdrv возьмите файлы usbportability.h, oddebug.c и oddebug.h, и скопируйте их в папку своего проекта.

3. Добавьте в проект компиляцию модуля oddebug.c.

Если у Вас проект AVR GCC, то добавьте модуль oddebug.c в список компиляции и линковки makefile:

Если у Вас проект IAR, то добавьте модуль oddebug.c в дерево модулей проекта.

4. Добавьте в модули, где нужно использовать отладочный вывод, подключение заголовка oddebug.h (директивой include).

#include «GenericHID.h»
#include
#include «oddebug.h» /* Макросы для отладочного вывода через UART */

5. Задайте глобальное макроопределение DEBUG_LEVEL, не равное 0.

Если у Вас проект AVR GCC, лучше всего это сделать в makefile проекта:

Модуль oddebug написан таким образом, что значение макроопределения DEBUG_LEVEL может быть либо 0, либо 1, либо 2:
DEBUG_LEVEL=0 отладка через UART не активна, код oddebug не компилируется, и макросы DBG1 и DBG2 не работают (хотя они могут присутствовать в коде пользователя).
DEBUG_LEVEL=1 работает только макрос DBG1, DBG2 не работает (хотя DBG2 может встречаться в коде пользователя).
DEBUG_LEVEL=2 работает и DBG1, и DBG2.

6. Перед главным циклом main сделайте вызов odDebugInit().

LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
odDebugInit();
DBG1(0x00, 0, 0); /* вывод debug: запуск цикла main */
sei();

Uart debug что это. Смотреть фото Uart debug что это. Смотреть картинку Uart debug что это. Картинка про Uart debug что это. Фото Uart debug что это

Как Вы уже наверное догадались, использование макросов DBG1 и DBG2 позволяет вести отладку на 2 уровнях, в зависимости от значения DEBUG_LEVEL. Если DEBUG_LEVEL = 2, то вывод может быть максимально подробным, так как будут выводить инфу и DBG1, и DBG2. Если DEBUG_LEVEL = 1, то отладочного вывода может быть меньше (будет выводится только макрос DBG1).

[Устранение проблем]

1. oddebug.h:39:5: warning: #warning «Debugging disabled because device has no UART»

2. Если у Вас чип, у которого нет имен TXEN или TXEN0, но задано имя TXEN1 или другое (например, так у чипа AT90USB162), то поправьте файл oddebug.h примерно так:

#if defined UCR
# define ODDBG_UCR UCR
#elif defined UCSRB
# define ODDBG_UCR UCSRB
#elif defined UCSR0B
# define ODDBG_UCR UCSR0B
#endif

#if defined UCR
# define ODDBG_UCR UCR
#elif defined UCSRB
# define ODDBG_UCR UCSRB
#elif defined UCSR0B
# define ODDBG_UCR UCSR0B
#elif defined UCSR1B
# define ODDBG_UCR UCSR1B
#endif

Аналогичным образом поправьте условия определения ODDBG_TXEN, ODDBG_UBRR, ODDBG_USR USR, ODDBG_UDRE UDRE, ODDBG_UDR UDR.

Готовый oddebug.h с внесенными исправлениями можете скачать по ссылке [2].

[Как подключить AVR к компьютеру]

Uart debug что это. Смотреть фото Uart debug что это. Смотреть картинку Uart debug что это. Картинка про Uart debug что это. Фото Uart debug что это

Uart debug что это. Смотреть фото Uart debug что это. Смотреть картинку Uart debug что это. Картинка про Uart debug что это. Фото Uart debug что это

Uart debug что это. Смотреть фото Uart debug что это. Смотреть картинку Uart debug что это. Картинка про Uart debug что это. Фото Uart debug что это

Uart debug что это. Смотреть фото Uart debug что это. Смотреть картинку Uart debug что это. Картинка про Uart debug что это. Фото Uart debug что это

Uart debug что это. Смотреть фото Uart debug что это. Смотреть картинку Uart debug что это. Картинка про Uart debug что это. Фото Uart debug что это

Uart debug что это. Смотреть фото Uart debug что это. Смотреть картинку Uart debug что это. Картинка про Uart debug что это. Фото Uart debug что это

Переходник USB TTL COM-port (он подключается с одной стороны к 6-pin коннектору FTDI, а с другой стороны к компьютеру по USB) можно купить готовый. Обычно такой переходник сделан по простейшей схеме на основе чипа FT232 (компания FTDI) или CP210x (компания Silicon Labs). Драйвер для переходника можно скачать с сайта соответствующей компании. Хорошие переходники USB to TTL Serial Cable FTDI (или на чипе CP210x) можно купить на eBay, dealextreme или aliexpress, есть даже предложения с бесплатной доставкой. При покупке выбирайте 5V версию (иногда бывают версии на 3.3V). Самый лучший вариант – когда можно выбрать перемычкой рабочие уровни порта TTL RS-232 (3.3V или 5V). Если уровни сигналов на переходнике USB to TTL и отлаживаемом устройстве не совпадают, то понадобятся последовательно включенные резисторы номиналом около 1…2 кОм.

[Использование класса USB CDC для отладки]

[Отладка кода в среде программирования Arduino IDE]

Переходник VCP можно также использовать для отладочного вывода и загрузки кода скетча (в платах Arduino, которые не оборудованы собственным портом VCP), что может помочь в отладке кода программы [2]. В Arduino IDE для этой цели используется оператор println.

[Назначение файлов и папок архива по ссылке [2]]

Проект USBtoSerial можно скомпилировать для всех 8-битных микроконтроллеров Atmel AVR USB (микроконтроллеры Atmel, имеющие на борту аппаратную поддержку интерфейса USB).

[Часто задаваемые вопросы, FAQ]

120428. Сделал вывод отладочной информации через преобразователь уровней, заработало. Однако в PuTTY отображаются иероглифы (кракозябры и псевдографика). Скриншот прилагаю.

Uart debug что это. Смотреть фото Uart debug что это. Смотреть картинку Uart debug что это. Картинка про Uart debug что это. Фото Uart debug что это

Источник

ОБОРУДОВАНИЕ
ТЕХНОЛОГИИ
РАЗРАБОТКИ

Блог технической поддержки моих разработок

Урок 21. Работа с UART через библиотеку HAL. Инициализация интерфейса и передача данных в блокирующем режиме. Отладка программ с помощью UART. Функция sprintf.

Uart debug что это. Смотреть фото Uart debug что это. Смотреть картинку Uart debug что это. Картинка про Uart debug что это. Фото Uart debug что это

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

Ведется много споров на тему, как лучше работать с UART, через HAL-библиотеку или используя CMSIS-регистры. Но, даже самые ярые сторонники последнего способа соглашаются, что во многих случаях библиотека HAL помогает сократить время разработки программ, не требует досконального знания оборудования. Собственно, для этого она и была создана.

Для многих приложений функциональности HAL-библиотеки вполне достаточно. И конечно, в полной мере ее использование оправдано для отладки программ через UART. Отладочные блоки это нечто временное. Не так важно, насколько оптимально они работают. А разбираться в регистрах CMSIS для создания тестовых модулей программы – обычно пустая трата времени. Все равно они будут удалены.

В справочнике HAL-библиотеки появилась таблица с функциями управления UART и страница с описанием этих функций. Просмотрите ее перед дальнейшим чтением урока, чтобы хотя бы приблизительно понимать, какие возможности предоставляет библиотека. Большинство функций понятны без подробного описания.

Инициализация, установка конфигурации UART.

Наверное, самая простая и очевидная задача. Давайте сделаем это с помощью STM32CubeMX, затем посмотрим, как конфигуратор инициализировал UART, какие HAL-функции использовал. На мой взгляд, применение STM32CubeMX для этой задачи вполне оправдано и главное удобно.

Создадим проект Lesson21_1.

Настроим систему тактирования на частоту 72 мГц. На всякий случай конфигурируем вывод светодиода общего назначения (PC13) как выход.

В нашей системе к компьютеру подключен UART1. Будем использовать его.

Выбираем вкладку в левом меню Connectivity, в нем же UART1. В окне Mode разрешаем работу UART в асинхронном режиме.

Uart debug что это. Смотреть фото Uart debug что это. Смотреть картинку Uart debug что это. Картинка про Uart debug что это. Фото Uart debug что это

На изображении микроконтроллера выводы UART PA9 (TX) и PA10(RX) стали зелеными, т.е. задействованными. Конфигуратор сам установил их режимы, разрешил тактирование UART от шины APB. И нам не пришлось разбираться, к какой шине он подключен, вспоминать, как устанавливается конфигурация портов ввода/вывода.

На установку конфигурации UART через регистры CMSIS в предыдущем уроке мы потратили много времени. Копались в документации, разбирались с устройством контроллера UART, назначением каждого бита, вычисляли константы, определяющие скорость обмена и т.п. Сейчас сделаем это за полминуты.

В окне Configuration выбираем закладку Parameter Settings и задаем нужные параметры. Скорость обмена в числовом виде (Baud Rate) и из двух вариантов выбираем длину слова (Word Lenth).

Uart debug что это. Смотреть фото Uart debug что это. Смотреть картинку Uart debug что это. Картинка про Uart debug что это. Фото Uart debug что это

Следующее поле (Parity) позволяет:

Uart debug что это. Смотреть фото Uart debug что это. Смотреть картинку Uart debug что это. Картинка про Uart debug что это. Фото Uart debug что это

Можно выбрать формат с одним или двумя стоповыми битами (поле StopBits).

Uart debug что это. Смотреть фото Uart debug что это. Смотреть картинку Uart debug что это. Картинка про Uart debug что это. Фото Uart debug что это

Выбираем один стоп-бит.

В расширенных параметрах (Advanced Parameters) можно разрешить только передачу или только прием (поле Data Direction).

Uart debug что это. Смотреть фото Uart debug что это. Смотреть картинку Uart debug что это. Картинка про Uart debug что это. Фото Uart debug что это

В последнем поле (Over Sampling) задано число выборок сигнала RX.

Пока можно на этом остановиться, но мы изучим еще вкладку GPIO Setting, с помощью которой можно изменить режимы выводов UART.

Для выходного сигнала TX можно задать частоту тактирования.

Uart debug что это. Смотреть фото Uart debug что это. Смотреть картинку Uart debug что это. Картинка про Uart debug что это. Фото Uart debug что это

Для входного сигнала RX конфигуратор позволяет подключить подтягивающий резистор к питанию или земле.

Uart debug что это. Смотреть фото Uart debug что это. Смотреть картинку Uart debug что это. Картинка про Uart debug что это. Фото Uart debug что это

Все, можно работать с UART. Завершаем создание проекта. Вот, что получилось у меня Lesson21_1.

Зарегистрируйтесь и оплатите. Всего 60 руб. в месяц за доступ ко всем ресурсам сайта!

Давайте откроем проект в Atollic TrueStudio, посмотрим и осознаем, что сделал конфигуратор. Возможно, нам в будущем потребуется изменять режим UART динамически или захочется задать его конфигурацию без использования STM32CubeMX.

В файле stm32f1xx_hal_msp.c :

Разрешается тактирование UART1.

Разрешается тактирование порта GPIOA. Выводы этого порта используются для UART1 (PA9 и PA10).

Задается режим для выводов PA9 и PA10.

GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

Как это все делать, мы уже знаем из предыдущих уроков. Новое – это конфигурирование UART.

Разберемся на примере нашего проекта. Все происходит в файле main.c.

Поле Instance обязательно должно быть задано. Оно определяет базовый адрес UART, т.е. какой именно UART будет использоваться.

huart1.Init.BaudRate = 9600;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;

И в завершение вызывается функция инициализации.

Все эти операции сделал за нас конфигуратор STM32CubeMX, но ничего не мешает выполнить их нам самим или изменить параметры интерфейса в ходе выполнения программы.

Работа с UART через HAL-библиотеку в блокирующем режиме.

Собственно работа с UART подразумевает выполнение двух операций передачи и приема данных.

Блокирующий режим означает, что во время выполнения этих операций программа “зависает” в функциях HAL. Она ждет окончания передачи или приема данных. Дальнейший ход выполнения программы на время останавливается. Возможно только выполнение функций обработки прерываний, если они разрешены.

Конечно, в реальных сложных программах непозволительная роскошь ничего не делать, а просто ждать, пока закончит работу аппаратный блок UART. В принципе теряется смысл аппаратной реализации UART. Можно сформировать сигналы обмена программно. Но такой принцип работы с UART подкупает своей простотой. Нет необходимости использовать прерывания или прямой доступ к памяти, конфигурировать эти узлы. Программа всегда предсказуема, не переходит на обработку аппаратных событий.

Особенно блокирующий режим востребован при отладке программ. Прежде всего, он требует меньше дополнительных установок. Вам необходимо передать на компьютер отладочные параметры, и хочется сделать это минимальными вмешательствами в структуру программы. Я бы отметил, что зависание программы на время передачи в этом случае может даже оказаться полезным. Вы точно знаете последовательность действий. Пока отладочное данное не было передано, программа дальше не пошла.

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

Передача данных в блокирующем режиме.

Для этого существует функция HAL_UART_Transmit.

HAL_StatusTypeDef HAL_UART_Transmit (UART_HandleTypeDef * huart, uint8_t * pData, uint16_t Size, uint32_t Timeout)

Применительно к передаче в блокирующем режиме:

Т.е. при использовании в блокирующем режиме возвращаемое значение функции HAL_UART_Transmit можно не проверять.

Собственно, из описания параметров HAL_UART_Transmit понятно, как передавать данные.

Попробуем в цикле отсылать на компьютер текстовое сообщение. Режим UART уже сконфигурирован. Остается в файл main.c вставить вызов функции передачи и задержку.

/* USER CODE BEGIN WHILE */

uint8_t str[] = «Проверка передачи UART\r\n\0»;

Для проверки загружаем программу в отладочную плату, запускаем CoolTerm.

Uart debug что это. Смотреть фото Uart debug что это. Смотреть картинку Uart debug что это. Картинка про Uart debug что это. Фото Uart debug что это

Не помню, писал ли я прежде, что CoolTerm можно не закрывать, а только отключать в момент загрузки программы в микроконтроллер кнопкой Discinnect и, при необходимости, включать кнопкой Connect.

Можно задать текстовую строку непосредственно в параметре функции.

/* USER CODE BEGIN WHILE */

#include
size_t *strlen (const char *str);

Strlen определяет конец строки по символу 0. Надо не забыть его добавить.

/* USER CODE BEGIN WHILE */

uint8_t str[] = «Проверка передачи UART\r\n\0»;

Если кого-то смущают предупреждения компилятора, то надо явно подключить файл библиотеки:

/* USER CODE BEGIN Includes */
#include
/* USER CODE END Includes */

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

Отладка программ с помощью последовательного порта.

У микроконтроллеров STM32 есть встроенный интерфейс SWD (Serial Wire Debug), через который можно не только загружать программу, но и производить ее отладку. Для подключения компьютера к SWD-интерфейсу необходимы дополнительные аппаратные средства, например, программатор ST-Link.

Будем считать, что на текущем этапе у нас нет такого программатора. Дальше речь идет об отладке программ с помощью интерфейса UART, через который плата подключена к компьютеру.

Основная функция средств отладки – это увидеть состояние программы, узнать значение переменных и т.п. Сделать это можно, передав отладочную информацию на компьютер через интерфейс UART. В нашем отладочном модуле он уже подключен к компьютеру. Данные отладки можно наблюдать с помощью любого терминала COM-порта, например, CoolTerm.

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

Остается разобраться, как передавать значения переменных. По сути это задача преобразования данных в текстовые строки. На сайте есть урок 30 Ардуино, посвященный этой теме. Каждый может выбрать удобный для себя способ или разработать свой собственный.

Функция sprintf.

К недостаткам его можно отнести требовательность функции sprintf к ресурсам микроконтроллера. Еще, как правило, в системах с микроконтроллерами она не поддерживает форматы с плавающей запятой. Найдем способ решения этой проблемы.

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

Описание функции выглядит так:

Обязательных параметров 2:

buf – указатель на текстовую строку, в которую будет записан результат;

format – строка форматирования.

Это функция с переменным числом аргументов. От строки форматирования зависит количество остальных параметров.

В самом простом случае в качестве строки форматирования используется текстовая строка, которая и будет передана, как результат работы функции.

sprintf((char *)str, «Проверка\n»);

Казалось бы, такое использование функции sprintf бессмысленно, но она позволяет добавлять в текстовую строку значения параметров. Для этого используются управляющие последовательности. Для каждого типа данных, своя последовательность. Они позволяют вставлять в текстовую строку данные различных форматов.

Управляющая последовательность имеет вид:

Обязательными элементами являются символ начала управляющей последовательности (%) и тип. С них и начнем. Я привел только самые необходимые из спецификаторов.

Спецификатор типаНазначение
%dВывод целого числа в десятичной системе исчисления.
%uВывод целого беззнакового числа в десятичной системе исчисления.
%xВывод целого числа в шестнадцатеричной системе исчисления.
%fВывод числа с плавающей запятой.
%cВывод символа с заданным кодом.
%sВывод строки с заданным указателем.

uint32_t x= 12345;
sprintf(str, «Значение переменной x= %d», x);

поместят в строку str следующую текстовую информацию:

Значение переменной x= 12345.

12345 – это значение переменной x в десятичном виде.

Управляющих последовательностей, а значит и отображаемых переменных может быть несколько. Давайте проверим все типы данных.

uint8_t str[100];
uint32_t x= 12345;
float y= 1.2345678;
uint8_t z= 0x61;
char str1[]= «Строка\0»;

Вот, что отобразил терминал.

Uart debug что это. Смотреть фото Uart debug что это. Смотреть картинку Uart debug что это. Картинка про Uart debug что это. Фото Uart debug что это

К текстовой строке добавились:

Спецификатор ширины задает минимальную ширину поля. Например, если задать ширину 5 для двухразрядного числа, то лишние 3 позиции будут содержать пробелы.

sprintf(str, «x= %5d\n», 12); // выведет «x= 12»

Можно лишние пробелы заполнить нулями.

sprintf(str, «x= %05d\n», 12); // выведет «x= 00012»

Если ширина будет меньше числа, то оно будет напечатано полностью.

sprintf(str, «x= %3d\n», 123456); // выведет «x= 123456»

Вывод чисел с плавающей запятой с помощью sprintf в средах программирования микроконтроллеров.

Во всех известных мне программных средствах для программирования микроконтроллеров на языке C функция sprintf не поддерживает вывод чисел с плавающей запятой.

Существует следующий способ решения этой проблемы.

float y= 18.2345678;
sprintf(str, «y= %f», y);

Мы уже проверяли. Результат ”y=”.

Поясню последовательность преобразования.

Выводим целую часть, печатаем децимальную точку.

Вычисляем и выводим дробную часть. Для этого:

Получаем следующую текстовую строку.

Надо понять принцип такого преобразования, и вы сможете выполнять его, не заглядывая в этот урок.

Последний обобщающий пример урока.

В цикле увеличиваются две переменные целочисленного и плавающего типа. Первая увеличивается на 1, вторая на 0.01. Значения переменных выводятся через UART.

Uart debug что это. Смотреть фото Uart debug что это. Смотреть картинку Uart debug что это. Картинка про Uart debug что это. Фото Uart debug что это

Прием данных UART в блокирующем режиме в этот урок не поместился. Этой задаче будет посвящен следующий урок.

Uart debug что это. Смотреть фото Uart debug что это. Смотреть картинку Uart debug что это. Картинка про Uart debug что это. Фото Uart debug что это

Автор публикации

Эдуард

20 комментариев на « Урок 21. Работа с UART через библиотеку HAL. Инициализация интерфейса и передача данных в блокирующем режиме. Отладка программ с помощью UART. Функция sprintf. »

Нет, ну это же несерьезно! Есть же DMA! Да, библиотека SD (та, которая идет в комплекте с Ардуино) корявая и нужно менять, но ведь проблема то глобальнее. Та же самая картина наблюдается в библиотеке работы с экраном, и даже слушание UART’а у меня сделано через опрос. В общем, я начал думать, что переписывание всех компонентов на HAL это не такая уж и глупая идея. Начал, конечно, с чего попроще — драйвера UART, который слушает поток данных от GPS. Интерфейс ардуино не позволяет прицепиться к прерыванию UART и выхватывать приходящие символы на лету. В итоге единственный способ получать данные — это постоянный опрос. Я, конечно, добавил vTaskDelay(10) в обработчик GPS, чтобы хоть немного снизить загрузку, но на самом деле это костыль. Первая мысль, конечно, была прикрутить DMA. Это даже сработало бы, если бы не протокол NMEA. Проблема в том, что в этом протоколе информация просто идет потоком, а отдельные пакеты (строки) разделяются символом переноса строки. При этом каждая строка может быть различной длины. Из-за этого заранее неизвестно сколько данных нужно принять. DMA так не работает — там количество байт нужно задавать заранее при инициализации пересылки. Короче говоря, DMA отпадает, ищем другое решение. Если посмотреть внимательно на дизайн библиотеки NeoGPS, то видно, что входные данные библиотека принимает побайтно, но значения обновляются только тогда, когда пришла вся строка (если быть точнее, то пакет из нескольких строк). Т.о. без разницы, кормить библиотеке байты по одному по мере приема, или потом все сразу. Так, что можно сэкономить процессорное время – сохранять принятую строку в буфер, при этом делать это можно прямо в прерывании. Когда строка принята целиком – можно начинать обработку. Вырисовывается следующий дизайн Хотя инициализация слизана из STM32GENERIC она полностью соответствует той, которую предлагает CubeMX

Сделайте кольцевой буфер и прием по DMA.
Рассчитать исходя из ваших настроек бодрейта за какое время заполнится 90% этого буфера. Организовать прерывание таймером при заполнении 90%, и в прерывании извлекать принятые данные из этого буфера в рабочий массив для последующей обработки. 10% оставить на время обработки прерывания — чтобы не переполнился буфер и не потерять ни 1 байта принятых данных.
Таким образом можно минимально использовать CPU на задачу приема.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *