Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.60/161: Рейтинг темы: голосов - 161, средняя оценка - 4.60
Yoomm_YY

stm32 HAL UART - не могу понять

12.11.2016, 14:51. Показов 31338. Ответов 42
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте, в STM32 я начинающий, приходится просить помощи.
Суть вот в чём. Надо принимать из последовательного порта строки. Строки обычно заканчиваются парами 0x0d 0x0a и могут быть разной длины. Принимать хочется, естественно, в прерывании (хотя-бы). HAL предоставляет только функцию чтения определённого количества байт. Потому решил эту функцию переделать.
Алгоритм такой: если символ 0x0d или 0x0a, то вместо него пишется 0x00 и указатель перемещается на начало буфера. В общем как-бы просто.
Теперь ближе к проблеме: когда отлавливаю только один символ завершения строки - безразлично какой 0x0d или 0x0a формируется нормальная строка. Если-же делаю проверку на оба символа, то почему-то на момент обработки прерывания как-бы в строке уже пришли оба символа:
посылаю: 0x31 0x32 0x33 0x34 0x35 0x0d 0x0a
получаю: 0x00 0x32 0x33 0x34 0x35 0x00
т.е. получается, что к моменту вызова HAL_UART_RxCpltCallback(huart)
следующий символ (0x0a) уже затирает начало строки....
Возникает впечатление, что программа выполняется не совсем последовательно...
Явно, Гипертерминал посылает пару 0x0d 0x0a практически без паузы, в то время как остальные символы с паузой. Если я указываю завершающие символы другие (например 4 и 5), то затирания не происходит.
Кто-нибудь может внести ясность.
Спасибо.
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
12.11.2016, 14:51
Ответы с готовыми решениями:

UART, HAL, stm32
Здравствуйте, только недавно узнал о существовании библиотеки HAL. Решил попробовать отправлять по блютуз модулю данные. Получается что-то...

STM32 HAL UART прерывания
Здравствуйте. Пытаюсь осуществить контакт с устройством по UART. Логика такая: c STM32 по UART в режиме прерываний посылаю определенную...

STM32 HAL прийом даних из UART
Всем привет, хочу принять массив с UART и записать его в буфер, для дальнейшего анализа. При передаче, проблем нет, просто...

42
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,183
12.11.2016, 17:00
Не использовать ХАЛ для вашего случае. Если без него совсем нельзя (а без него можно) - то не использовать его только для UARTа.

А на счет того, что у вас пропускается символ - возможно что вы в прерывании делаете много операций и второй символ не считывается.
Т.е. когда пришел 0x0d вы его отловили и начали что-то долго делать, пока это выполнялось в прерывании, пришел 0x0a но его вы не считали потому что еще не вышли из предыдущего прерывания.
Варианты решения (кроме тех, что я озвучил выше)
- увеличить частоту МК до максимума,
- делать в прерывании минимум действий (HAL там и без вас нагружает МК туевой хучей кода).
Если нужен пример как ловить данные из УАРТа без хала но с его конфигурацией - пишите, дам пример.
0
0 / 0 / 0
Регистрация: 17.03.2012
Сообщений: 488
12.11.2016, 17:16
Какой камень конкретно? stm32f103, stm32f407?
У меня получилась хорошая библиотека, использую HAL + DMA, приём и передача в любом месте программы.
Я её в ближайший месяц-два оформлю её в отдельный исходник и выложу в интернет. Новая версия под 407.
0
Yoomm_YY
12.11.2016, 18:55
otixsom, на скорости 9600 работает UART, чтобы мк не успел... нереально.

tmttyb, с dma это интересно, вообще-то сам хотел с ним....
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,183
12.11.2016, 20:18
Цитата Сообщение от Yoomm_II
otixsom, на скорости 9600 работает UART, чтобы мк не успел... нереально.
Ну звыняйте, экстрасенсы в отпуске. Гадать по текстам без кода не умеем.
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 886
12.11.2016, 21:49
И главное логику работы продумать.
если нарисуете на бумажке и проделаете те же ждействия что в программе - сразу поймете ошибку в алгоритме при анализе двух символов конца строки.

HALы, шмалы, SPL тут не при чем
0
0 / 0 / 0
Регистрация: 26.04.2010
Сообщений: 1,445
13.11.2016, 00:44
HAL_UART_RxCpltCallback(huart) вызывается, когда принято указанное количество байт. Не посте каждого байта.
0
0 / 0 / 0
Регистрация: 23.05.2012
Сообщений: 214
13.11.2016, 10:45
Переусложняете все. Делать через прерывание. В функции HAL_UART_RxCpltCallback при приходе каждого байта проверять на содержимое, если символ то в буфер, если 0d 0a то послать буфер в прогу. Скорости обработки хватит с лихвой на любом стм при скорости хоть 115200.
Вот все очень доходчиво объяснено https://www.youtube.com/watch?v=J0Rgh1N ... k&index=14
0
Yoomm_YY
13.11.2016, 19:41
Спасибо за ответы, но ничего полезного нет...
Полагал, что с этим уже кто-то сталкивался, но, видимо, не здесь...
Ещё раз: То что предлагает HAL - не подходит. Причина - там всё заточено под фиксированную длину сообщений. Реально длина сообщений разная. Потому пытаюсь переделать функции HAL-а для своих (а может быть и не только своих) нужд.
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,183
13.11.2016, 20:02
Так я вам сразу написал -
Если нужен пример как ловить данные из УАРТа без хала но с его конфигурацией - пишите, дам пример.
В двух словах - настраиваете UART в Хале через Куб, но без прерываний. Так куб не генерит все ненужное. Далее просто
задаете приоритет:
Code
1
2
HAL_NVIC_SetPriority(USORT1_IRQn, 10, 0);
HAL_NVIC_EnableIRQ(USORT1_IRQn);
и включаете прерывания:
Code
1
2
__HAL_UART_ENABLE_IT(&huart2, UART_IT_RXNE);
__HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE);
затем
Code
1
2
3
4
5
6
7
8
void USORT2_IRQHomdler(void)
{
if ((__HAL_UART_GET_FLAG(&huart2, UART_FLAG_RXNE) != RESIT) && (__HAL_UART_GET_IT_SOURCE(&huart2, UART_IT_RXNE) != RESIT))
{
// Your code here
}
__HAL_UART_CLEAR_PEFLAG(&huart2);
}
Все.
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 886
13.11.2016, 21:04
можно только переделать USORTx_IRQHomdler
(не вызывать HAL) а обработать как надо.
Вызывать ....Receive_IT один раз
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,183
13.11.2016, 21:18
Цитата Сообщение от x893
можно только переделать USORTx_IRQHomdler
(не вызывать HAL) а обработать как надо.
Вызывать ....Receive_IT один раз
Можно, но как-то это не совсем правильно. Ну и там нет реакции на UART_IT_IDLE что обычно часто нужно чтоб понять пришли все данные или нет.
Думаю что ТС изобретает свой велосипед из-за того, что не знает о таком прерывании, поэтому городит огород из спец символов.
0
1 / 1 / 0
Регистрация: 10.09.2015
Сообщений: 171
13.11.2016, 21:30
Цитата Сообщение от Yoomm_II
Спасибо за ответы, но ничего полезного нет...
Полагал, что с этим уже кто-то сталкивался, но, видимо, не здесь...
Ещё раз: То что предлагает HAL - не подходит. Причина - там всё заточено под фиксированную длину сообщений. Реально длина сообщений разная. Потому пытаюсь переделать функции HAL-а для своих (а может быть и не только своих) нужд.
Советы Вам дали вполне нормальные. В Вашем случае HAL, SPL, CMSIS абсолютно безразлично (более того безразлично даже через что происходит получение данных UART, SPI, I2C или что-то другое), т.к. вопрос на самом деле не к получению данных, а ловля конца передачи, другими словами задача состоит из двух подзадач: получение данных и парсинг полученных данных. Парсинг конечно громко сказано - искать нужно всего два байта, но тем не менее... Вам никто не может помочь по той причине, что задача имеет огромное количество вариантов решения, зависит только от фантазии и навыков. Кроме того, moksir дал один из вариантов решения - Вам осталось только его реализовать.
Про фиксированную длину - видимо имеется ввиду работа через DMA. Если Вы организуете с помощью него циклический буфер, то сможете получать произвольное количество данных. При использовании прерывания вопрос о фиксированности вообще не уместен. Так что HAL здесь не причем. Экспериментируйте. Посмотрите примеры от ST - они очень простые.

Цитата Сообщение от otixsom
В двух словах - настраиваете UART в Хале через Куб, но без прерываний. Так куб не генерит все ненужное. Далее просто
задаете приоритет:
Что Куб не генерит? Если имеете в виду включение прерывания, то в Кубе надо просто галочку поставить на закладке "NVIC Settings".
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,183
13.11.2016, 21:48
Цитата Сообщение от vbokom
Цитата Сообщение от otixsom
В двух словах - настраиваете UART в Хале через Куб, но без прерываний. Так куб не генерит все ненужное. Далее просто
задаете приоритет:
Что Куб не генерит? Если имеете в виду включение прерывания, то в Кубе надо просто галочку поставить на закладке "NVIC Settings".
Да, вот для моего примера коментом выше как раз и не нужно настраивать прерывания в Кубе
0
1 / 1 / 0
Регистрация: 10.09.2015
Сообщений: 171
13.11.2016, 22:22
Цитата Сообщение от otixsom
Цитата Сообщение от vbokom
Цитата Сообщение от otixsom
В двух словах - настраиваете UART в Хале через Куб, но без прерываний. Так куб не генерит все ненужное. Далее просто
задаете приоритет:
Что Куб не генерит? Если имеете в виду включение прерывания, то в Кубе надо просто галочку поставить на закладке "NVIC Settings".
Да, вот для моего примера коментом выше как раз и не нужно настраивать прерывания в Кубе
Согласен, в этом случае лучше ручками.
0
1 / 1 / 0
Регистрация: 10.09.2015
Сообщений: 171
13.11.2016, 22:50
Цитата Сообщение от Yoomm_II
Алгоритм такой: если символ 0x0d или 0x0a, то вместо него пишется 0x00 и указатель перемещается на начало буфера. В общем как-бы просто.
Теперь ближе к проблеме: когда отлавливаю только один символ завершения строки - безразлично какой 0x0d или 0x0a формируется нормальная строка. Если-же делаю проверку на оба символа, то почему-то на момент обработки прерывания как-бы в строке уже пришли оба символа:
посылаю: 0x31 0x32 0x33 0x34 0x35 0x0d 0x0a
получаю: 0x00 0x32 0x33 0x34 0x35 0x00
т.е. получается, что к моменту вызова HAL_UART_RxCpltCallback(huart)
следующий символ (0x0a) уже затирает начало строки....
Когда Вы приняли 0x0d, вы заменили 0x0d на 0x00 (получили 0x31 0x32 0x33 0x34 0x35 0x00) и перешли на начало буфера. Затем получаете 0x0a и заменяете его на 0x00, но указатель стоит уже на начале буфера, поэтому затираете первый символ и получаете (0x00 0x32 0x33 0x34 0x35 0x00). А т.к. символы идут "без паузы", то Вами это и воспринимается как "как-бы в строке уже пришли оба символа".
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 886
13.11.2016, 23:00
Цитата Сообщение от vbokom
Цитата Сообщение от Yoomm_II
Алгоритм такой: если символ 0x0d или 0x0a, то вместо него пишется 0x00 и указатель перемещается на начало буфера. В общем как-бы просто.
Теперь ближе к проблеме: когда отлавливаю только один символ завершения строки - безразлично какой 0x0d или 0x0a формируется нормальная строка. Если-же делаю проверку на оба символа, то почему-то на момент обработки прерывания как-бы в строке уже пришли оба символа:
посылаю: 0x31 0x32 0x33 0x34 0x35 0x0d 0x0a
получаю: 0x00 0x32 0x33 0x34 0x35 0x00
т.е. получается, что к моменту вызова HAL_UART_RxCpltCallback(huart)
следующий символ (0x0a) уже затирает начало строки....
Когда Вы приняли 0x0d, вы заменили 0x0d на 0x00 (получили 0x31 0x32 0x33 0x34 0x35 0x00) и перешли на начало буфера. Затем получаете 0x0a и заменяете его на 0x00, но указатель стоит уже на начале буфера, поэтому затираете первый символ и получаете (0x00 0x32 0x33 0x34 0x35 0x00). А т.к. символы идут "без паузы", то Вами это и воспринимается как "как-бы в строке уже пришли оба символа".

Именно поэтому я раньше и написал, что надо на бумажке нарисовать свой алгоритм и подумать как он будет работать, а не писать на форум, что у STM ничего не работает.

P.S. Конечно инлийские товарищи допускают отдельные ошибки, но тексты есть - можно всегда посмотреть и исправить.
P.P.S. ошибка настолько очевидная, что желательно было бы её найти создателю кода.
0
Yoomm_YY
14.11.2016, 03:25
Когда Вы приняли 0x0d, вы заменили 0x0d на 0x00 (получили 0x31 0x32 0x33 0x34 0x35 0x00) и перешли на начало буфера. Затем получаете 0x0a и заменяете его на 0x00, но указатель стоит уже на начале буфера, поэтому затираете первый символ и получаете (0x00 0x32 0x33 0x34 0x35 0x00). А т.к. символы идут "без паузы", то Вами это и воспринимается как "как-бы в строке уже пришли оба символа".
Да, точно, только ведь получение 0x0a должно быть УЖЕ В СЛЕДУЮЩЕМ прерывании! А в том, в котором пришло 0x0d и было поменяно на 0x00 всё отправляется на обработку, т.е. на копирование полученной 0-терминированной строки. Вот ЭТО и НЕПОНЯТНО!
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 886
14.11.2016, 03:54
Ориентируйтесь на пацанов из MTK - они такие глупости даже не задают. Просто чуть-чуть включите мозг. Не надо быть на уровне электриков.
А вдруг придется работать в системе раннего обнаружения подводных лодок - и FFT будете тоже здесь спрашивать ? а если с летунами - 29 или 30 су , кто будет вам говорить про usart ?

Самому надо как то использовать свои ресурсы.
Лучшая тренировка - двумя руками, с двух сторон писать фразы. Одновременно двумя руками.
только надо сразу высчитать длину фразы, что бы все буквы вошли.

P.S. Вот наколбасил !
0
1 / 1 / 0
Регистрация: 10.09.2015
Сообщений: 171
14.11.2016, 09:15
[QUOTE="Yoomm_II"][QUOTE="Цитата:[/QUOTE]
Когда Вы приняли 0x0d, вы заменили 0x0d на 0x00 (получили 0x31 0x32 0x33 0x34 0x35 0x00) и перешли на начало буфера. Затем получаете 0x0a и заменяете его на 0x00, но указатель стоит уже на начале буфера, поэтому затираете первый символ и получаете (0x00 0x32 0x33 0x34 0x35 0x00). А т.к. символы идут "без паузы", то Вами это и воспринимается как "как-бы в строке уже пришли оба символа".
Да, точно, только ведь получение 0x0a должно быть УЖЕ В СЛЕДУЮЩЕМ прерывании! А в том, в котором пришло 0x0d и было поменяно на 0x00 всё отправляется на обработку, т.е. на копирование полученной 0-терминированной строки. Вот ЭТО и НЕПОНЯТНО!
Кода конечно нет, но да ладно включим режим ясновидения.
Вы, насколько я вижу, пытаетесь получить нуль-терминальную строку. В прерывании получаете символы и кладете их в буфер, а обработку производите в основном теле программы - это правильно. Но в основном теле, здесь рассмотреть не получилось, толи медленный вывод, толи задержка стоит, Вы работаете с тем же буфером в который производите ввод принятых байт. За время этой задержки приходит новый байт 0x0a, который в прерывании спокойно кладется в нулевую ячейку буфера - и вуаля... получаем битым первый символ.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
14.11.2016, 09:15
Помогаю со студенческими работами здесь

UART на STM32 (не могу запустить)
Приветствую, коллеги! Сижут, пытаюсь запустить USORT на STM32F103RET6. Хочется просто послать символ в терминал для начала. Использую...

Код, управляющий ШИМ, АЦП и UART. Команды от ПК. Не могу понять, почему не работает
По задумке, прога всё инициализирует и ждёт прерывания с номером команды от UART. Когда номер приходит, обновляется значение текущей...

Stm32f4 Uart Hal
Здравствуйте. Изучаю плату STM32F4 discovery. Для неё имеется куча примеров, спасибо. А мне вот надо UART6 (тот который...

STM32F103C8T6 HAL UART
Добрый вечер. Ситуация такая, не могу понять как правильно реализовать прием данных по UART не использую к примеру прерывания. У меня...

STM32F407 + HAL + UART
Доброго времени суток! Изучаю основы работы UART. Отладочная плата STM32F407 Discovery. Библиотека HAL. Подключаю через UART...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
My Business CRM
MaGz GoLd 16.04.2026
Всем привет, недавно возникла потребность создать CRM, для личных нужд. Собственно программа предоставляет из себя базу данных клиентов, в которой можно фиксировать звонки, стадии сделки, а также. . .
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . . а удачный момент так и не приходит.
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица. Задача: зафиксировать три левых колонки в отчете. Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) / / . . .
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача №1: при указании работ (справочник РаботыПоРемонтуСпецтехники),. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru