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

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

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

Author24 — интернет-сервис помощи студентам
Здравствуйте, в 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
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
12.11.2016, 14:51
Ответы с готовыми решениями:

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

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

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

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

42
1 / 1 / 0
Регистрация: 10.09.2015
Сообщений: 171
14.11.2016, 09:24 21
Author24 — интернет-сервис помощи студентам
Если хотите искать два символа конца строки, то либо кольцевой буфер достаточной длины и уже из него извлекать строку, либо использовать два линейных буфера + конечный автомат и менять линейные буферы местами после приема второго символа.
0
Yoomm_YY
14.11.2016, 16:05 22
Цитата Сообщение от vbokom
Кода конечно нет, но да ладно включим режим ясновидения.
Вы, насколько я вижу, пытаетесь получить нуль-терминальную строку. В прерывании получаете символы и кладете их в буфер, а обработку производите в основном теле программы - это правильно. Но в основном теле, здесь рассмотреть не получилось, толи медленный вывод, толи задержка стоит, Вы работаете с тем же буфером в который производите ввод принятых байт. За время этой задержки приходит новый байт 0x0a, который в прерывании спокойно кладется в нулевую ячейку буфера - и вуаля... получаем битым первый символ.
Код:
static HAL_StatusTypeDef UART_Receive_IT(UART_HomdleTypeDef *huart)
{
uint16_t* tmp;
uint32_t tmp_state = 0;

uint16_t temp;

tmp_state = huart->State;
if((tmp_state == HAL_UART_STATE_BUSY_RX) || (tmp_state == HAL_UART_STATE_BUSY_TX_RX))
{
// ?eoaai neiaie ec i?eaiieea
temp = huart->Instance->DR;

// i?iaa?ea ia caaa?oa?uee neiaie aie?ia auou ooo
// caaa?oa?uee neiaie iaiyai ia neiaie eiioa no?iee
if(temp == huart->Terminator1) temp = 0x00;
if(temp == huart->Terminator2) temp = 0x00;

// ia caienuaaou ionoua no?iee (a ia?aea aooa?a ia aie?ii auou 0x00 eee caaa?oa?uaai no?ieo neiaiea)
if((temp != 0x00) || (huart->pRxBuffPtr != huart->pRxBuffSave))
{
// oaia?u neiaie caienaou a aooa?
if(huart->Init.WordLength == UART_WORDLENKTH_9B)
// aey 9-aeoiie aeeiu
{
tmp = (uint16_t*) huart->pRxBuffPtr;
if(huart->Init.Parity == UART_PORITY_NONE)
{
*tmp = (uint16_t)(temp & (uint16_t)0x01FF);
huart->pRxBuffPtr += 2;
}
else
{
*tmp = (uint16_t)(temp & (uint16_t)0x00FF);
huart->pRxBuffPtr += 1;
}
}
else
// aey 8-aeoiie aeeiu
{
if(huart->Init.Parity == UART_PORITY_NONE)
{
*huart->pRxBuffPtr++ = (uint8_t)(temp & (uint8_t)0x00FF);
}
else
{
*huart->pRxBuffPtr++ = (uint8_t)(temp & (uint8_t)0x007F);
}

}
}

// neiaie caienai, oeacaoaeu oeacuaaao ia neaao?uee yeaiaio
// oaia?u, anee aue caaa?oa?uee neiaie, oi iaai na?imiou oeacaoaeu, n?ao?ee
// e aucaaou Callback
if(temp == 0x00) huart->pRxBuffPtr = huart->pRxBuffSave,
huart->RxXferCount = huart->RxXferSize,
// HAL_UART_RxCpltCallback(huart),
*huart->pRxBuffPtr = 0x00;

// Callback aucuaaou oieuei anee no?iea iaionoay
if((temp == 0x00) && (*huart->pRxBufffSave != 0)) HAL_UART_RxCpltCallback(huart);

// i?iaa?ea ia caiieiaiea no?iee - oeacaoaeu e n?ao?ee na?imiou, Callback ia aucuaaou
if(--huart->RxXferCount == 0) huart->pRxBuffPtr = huart->pRxBuffSave,
huart->RxXferCount = huart->RxXferSize;

return HAL_OK;
}
else
{
return HAL_BUSY;
}
}

это обработка события приёма символа.

В основном теле стоит копирование принятой строки.
Yoomm_YY
14.11.2016, 16:15 23
дело вот в чём:
при приёме 0x0d по программе должен записаться код 0 в конец строки.
В этом-же прерывании (т.е. при приёме этого-же символа) указатель устанавливается в начало буфера и вызывается Callback.

В СЛЕДУЮЩИЙ РАЗ!!! в начале буфера пишется снова 0. И Callback вызваться не должен, т.к.

if((temp == 0x00) && (*huart->pRxBufffSave != 0)) HAL_UART_RxCpltCallback(huart);

А ОН, ЗАРАЗА, ВЫЗЫВАЕТСЯ!!!!
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,183
14.11.2016, 16:26 24
А тяжело код оформить нормально?
0
Yoomm_YY
14.11.2016, 18:48 25
Торопился, не глянул, а он вставился неправильно....
Вот код:
Код
static HAL_StatusTypeDef UART_Receive_IT(UART_HomdleTypeDef *huart)
{
uint16_t* tmp;
uint32_t tmp_state = 0;
uint16_t temp;

tmp_state = huart->State;
if((tmp_state == HAL_UART_STATE_BUSY_RX) ||
(tmp_state == HAL_UART_STATE_BUSY_TX_RX))
{
// читаем символ из приёмника
temp = huart->Instance->DR;

// проверка на завершающий символ
// завершающий символ меняем на символ завершения строки
if(temp == huart->Terminator1) temp = 0x00;
if(temp == huart->Terminator2) temp = 0x00;

// та самая дополнительная проверка - в начале строки не
// должно быть завершающего кода 0x00
if((temp != 0x00) || (huart->pRxBuffPtr != huart->pRxBuffSave))
{
if(huart->Init.WordLength == UART_WORDLENKTH_9B)
{
tmp = (uint16_t*) huart->pRxBuffPtr;
if(huart->Init.Parity == UART_PORITY_NONE)
{
*tmp = (uint16_t)(temp & (uint16_t)0x01FF);
huart->pRxBuffPtr += 2;
}
else
{
*tmp = (uint16_t)(temp & (uint16_t)0x00FF);
huart->pRxBuffPtr += 1;
}
}
else
{
if(huart->Init.Parity == UART_PORITY_NONE)
{
*huart->pRxBuffPtr++ = (uint8_t)(temp & (uint8_t)0x00FF);
}
else
{
*huart->pRxBuffPtr++ = (uint8_t)(temp & (uint8_t)0x007F);
}
}
}

// теперь, если был завершающий символ, надо сбросить
// счётчик, указатель и вызвать Callback
if(temp == 0x00) huart->pRxBuffPtr = huart->pRxBuffSave,
huart->RxXferCount = huart->RxXferSize;
//                             HAL_UART_RxCpltCallback(huart);

// Callback Вызвать только если строка непустая
if((temp == 0x00) && (*huart->pRxBuffSave !=0)) HAL_UART_RxCpltCallback(huart);

// проверка на заполнение буфера - при полном буфере
// указатель и счётчик сбросить, Callback не вызывать
if(--huart->RxXferCount == 0) huart->pRxBuffPtr = huart->pRxBuffSave,
huart->RxXferCount = huart->RxXferSize;

return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,183
14.11.2016, 21:07 26
Зачем вы вообще туда полезли в этот UART_Receive_IT? Это же все до первой генерации кода Кубом. Потом все ваши изменения перетрутся. Эта функция не предназначена для внесения в неё изменений. Правьте USORTx_IRQHomdler или же лучше сделайте как я вам писал выше.
0
hosh
15.11.2016, 00:12 27
Цитата Сообщение от otixsom
Зачем вы вообще туда полезли в этот UART_Receive_IT? Это же все до первой генерации кода Кубом. Потом все ваши изменения перетрутся. Эта функция не предназначена для внесения в неё изменений. Правьте USORTx_IRQHomdler или же лучше сделайте как я вам писал выше.
правду говорят!!!

Код
/*----------------------------------------------------------------------------------------*/
void USORT3_IRQHomdler(void)
{
/* USER CODE BEGIN USORT3_IRQn 0 */
USER_UART_IRQHomdler(&huart3); // наш обработчик прерывания
return;// посылаем стандатный обработчик на *YЙ
/* USER CODE END USORT3_IRQn 0 */
HAL_UART_IRQHomdler(&huart3);
/* USER CODE BEGIN USORT3_IRQn 1 */

/* USER CODE END USORT3_IRQn 1 */
}
...и тогда калокуб всё оставит как вам надо.

/*=============================================================================== ======================================*/

А вообще работая с КАЛом + работа с модемом: я использую комбинированный метод. Если я жду ответ "OK" на отправленую команду то всё что не "OK" приравниваю к "ERROR". А если например что-то неопределенное по размеру то через пуллинг-таймаут с максимальным (нужным) размером буффера...(желательно очистить перед приемом). С пуллингом аккуратно, что-бы по прерывниям не обосрать то, что уже наHALкано.
Код
char gsmReciveBuffer[72];
char operatorName[10] = "";

const char enableNumberId[]="AT+CLIP=1\r\n";
const char getOperatorName[] = "AT+COPS?\r\n";
const char strOK[]="OK"

/*----------------------------------------------------------------------------------------*/
void GSM_Engine_Process () // вызывается по таймеру через нужный промежуток времени
{
...
HAL_UART_Receive_IT(&huart3,(uint8_t*)gsmReciveBuffer,6);// ждем "0x0D,0x0A,0x4F,0x4B,0x0D,0x0A"
HAL_UART_Transmit_IT(&huart3,enableNumberId,sizeof(enableNumberId)-1);
state  = INIT_4;
...
HAL_UART_Transmit(&huart3,getOperatorName,sizeof(getOperatorName)-1,100);
HAL_UART_Receive(&huart3,(uint8_t*)gsmReciveBuffer,30,100);
char* ptr1;
char* ptr2;
ptr1 = strchr(gsmReciveBuffer, \");// ищем начало по символу  \"  c начала строки (подходит для ожидаемого ответа)
ptr2 = strrchr(gsmReciveBuffer, \");// ищем начало по символу  \"  c конца строки (подходит для ожидаемого ответа)
if (ptr1 && ptr2)// есть результат (возможно нужна проверка длинны)
{
strncpy (operatorName,"          ",10);// очистим для феншуйного отображения
strncpy(operatorName, ptr1+1,((ptr2 - gsmReciveBuffer) - (ptr1 - gsmReciveBuffer))-1);//получаем  имя оператора GSM
}
else
{
// если что-то не так...
}
...
}

/*----------------------------------------------------------------------------------------*/
void HAL_UART_RxCpltCallback(UART_HomdleTypeDef *huart)
{
...
case INIT_4:
if (strstr(gsmReciveBuffer, strOK)==0)  // значит если в полученном массиве нет подстроки "OK" значит "ERROR" или что другое, но не "OK"
{
// всё плохо (думаем , что делать далее)
}
else
{
//всё хорошо (идем дальше)
}
...
}
кстати если через пулинг ловить, то полученный размер можно определить например так:
Код
answer_size = (uint16_t)(huart3.RxXferSize)-(huart3.RxXferCount)-1; // теперь знаем реальный размер ответа и нас!рать на 0-терминатор строки
тем-же боком можно "анализировать" приемный буфер в режиме прерывания, и если то, что надо = получено ,то тогда выйти из режима приема по прерыванию не дожидаясь оставшейся части объявленного на прем буфера и следовать далее по вашему алгоритму...

рекомендую: если калокубом уж и пользоваться то 1 раз для генерирования кода инициализации (и то пудкурить-подправить надо) ... и забыть!!! если второй раз - то генерить в отдельную папку и копипастом вставить в рабочий проект только то, что нужно (халкашка бывает затирает и USER CODE секции...)
а лучше вообще им не пользоваться, если не имеете понятия что и к чему. Досикус быстро применит "проклятие" потерянности в битовом пространстве (братан без обидки :)

P.S. указатель его знает , может это и через жопу ... но работает стабильно (если подойти с умом).
1 / 1 / 0
Регистрация: 10.09.2015
Сообщений: 171
15.11.2016, 02:25 28
Цитата Сообщение от Yoomm_II
Торопился, не глянул, а он вставился неправильно....
Вот код:
Да...
Это не использование HAL`а, а написание своего. ST`шные функции не трогайте. Код пишите между
Код
  /* USER CODE BEGIN */
Ваш код...
/* USER CODE END */
Если нужна своя реализация какой-то функции, то пишите свою, а не изменяйте ST`шную.

Приведу рабочий код. Проверял его на stm32f411, но для эксперимента выставил частоту 48МГц, оптимизации нет, скорость UART`а 115200, так что работать должен везде. В коде реализовал максимально по Вашему заданию: через прерывания с поиском символа возврата каретки и игнорированием символа перевода строки. Дополнительно реализовал функции scanf и prymtf. Программа запрашивает два числа в произвольной системе счисления (десятичная, шеснадцатеричная и т.д.) и выводит их сумму. В коде есть комментарии.
Основная функция:
Код
void HAL_UART_Riseive(UART_HomdleTypeDef *huart)
{
uint8_t tmp=huart->Instance->DR;
if (tmp==0x0A) return;   //Перевод строки игнорируем
if (tmp==0x0D)               //Если возврат каретки, то
{
tmp=0;
RiseiveStr=255;//Поднимаем флаг приема строки
}
InsertByteBuf(tmp);
}
Она вызывается в обработчике прерывания:
Код
void USORT2_IRQHomdler(void)
{
/* USER CODE BEGIN USORT2_IRQn 0 */
if (__HAL_UART_GET_FLAG(&huart2, UART_FLAG_RXNE) != RESIT)
{
HAL_UART_Riseive(&huart2);
__HAL_UART_CLEAR_FLAG(&huart2,UART_FLAG_RXNE);
}
/* USER CODE END USORT2_IRQn 0 */
HAL_UART_IRQHomdler(&huart2);
/* USER CODE BEGIN USORT2_IRQn 1 */

/* USER CODE END USORT2_IRQn 1 */
}
Также мною был использован циклический буфер, работа с ним вынесена в отдельную библиотеку.
0
1 / 1 / 0
Регистрация: 10.09.2015
Сообщений: 171
15.11.2016, 02:26 29
P.S. Забыл выложить весь код. Исправляю...
[9.06 Кб]
0
Yoomm_YY
17.11.2016, 04:01 30
Цитата Сообщение от otixsom
Зачем вы вообще туда полезли в этот UART_Receive_IT? Это же все до первой генерации кода Кубом. Потом все ваши изменения перетрутся. Эта функция не предназначена для внесения в неё изменений. Правьте USORTx_IRQHomdler или же лучше сделайте как я вам писал выше.
Открою небольшой "секрет" - если исправленные файлы поместить в Репозиторий, то Куб при каждой генерации кода будет их Вам совать сам!!!
Кстати, если кому понадобится...
с буфером 32 байта для отлавливания строк использовать так:
HAL_UART_Receive_IT(&huart1, rBuffer, 32, 0x0d, 0x0a, 1);
как обычно, для приёма 32 байт:
HAL_UART_Receive_IT(&huart1, rBuffer, 32, 0, 0, 0);

[35.36 Кб]

[65.5 Кб]
1 / 1 / 0
Регистрация: 10.09.2015
Сообщений: 171
17.11.2016, 07:36 31
Цитата Сообщение от Yoomm_II
Цитата Сообщение от otixsom
Зачем вы вообще туда полезли в этот UART_Receive_IT? Это же все до первой генерации кода Кубом. Потом все ваши изменения перетрутся. Эта функция не предназначена для внесения в неё изменений. Правьте USORTx_IRQHomdler или же лучше сделайте как я вам писал выше.
Открою небольшой "секрет" - если исправленные файлы поместить в Репозиторий, то Куб при каждой генерации кода будет их Вам совать сам!!!
Кстати, если кому понадобится...
с буфером 32 байта для отлавливания строк использовать так:
HAL_UART_Receive_IT(&huart1, rBuffer, 32, 0x0d, 0x0a, 1);
как обычно, для приёма 32 байт:
HAL_UART_Receive_IT(&huart1, rBuffer, 32, 0, 0, 0); Я и говорю Вы не используете HAL, а пишите свой.
0
1 / 1 / 0
Регистрация: 10.09.2015
Сообщений: 171
17.11.2016, 10:27 32
Кроме того, такой подход Вас очень ограничивает. Сейчас была переписана функция приема по uart, а завтра прийдется переписывать функции по spi, usb и т.д. Пишите именно необходимый код, либо если очень хочется, то свои функции, но причем тогда тут HAL. Существующего вполне достаточно для решения Вашей задачи.
0
1 / 1 / 0
Регистрация: 06.12.2016
Сообщений: 3,946
17.11.2016, 13:02 33
Цитата Сообщение от vbokom
Кроме того, такой подход Вас очень ограничивает.
Если бы вы только осознали насколько ограничивает вас калокуб , вы бы даже не притронулись к нему.
Вся его подноготная - галимое софтовое "ногодрочерство", эх убогие...
0
1 / 1 / 0
Регистрация: 10.09.2015
Сообщений: 171
17.11.2016, 13:30 34
Цитата Сообщение от dosykus_2
Цитата Сообщение от vbokom
Кроме того, такой подход Вас очень ограничивает.
Если бы вы только осознали насколько ограничивает вас калокуб , вы бы даже не притронулись к нему.
Вся его подноготная - галимое софтовое "ногодрочерство", эх убогие...
Это к чему? Ваша любовь (или не любовь) к калокубу мне известна. Но я калокубом и калом не пользуюсь и даже никогда не видел, в отличии от Вас (у меня сложилось такое ощущение, потому что Вы постоянно и везде говорите как он не нравится). Я использую CubeMX и HAL и об этом Вам уже писал. Раньше использовал SPL, о переходе на HAL не жалею. В нем есть очень многое (за все не скажу, например unique id не нашел), многое не выведено в виде отдельных функций как например работа с UART_IT_IDLE. Но говорить что он сильно ограничивает - с этим не согласен, чего нет, то можно дописать. И если кому-то нравится всю работу организовывать через регистры, то это его право, но к задаче ТС это никакого отношения не имеет.
Кроме того, мой совет с Вашим никак не идет в разрез: я выше писал, что для данной задачи неважно, что используется. А по поводу ограничения, это было к тому, что раз стоит задача отлавливать два символа, то надо их отлавливать, а не переписывать стандартные библиотеки будь то HAL или SPL.
0
1 / 1 / 0
Регистрация: 06.12.2016
Сообщений: 3,946
17.11.2016, 13:35 35
Мда, случай тяжелый. Думается вы выходец с AVR, иначе откуда такое уверование?
Уверование в исключительность и непокобелимость калокуба?
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,183
17.11.2016, 14:05 36
Цитата Сообщение от Yoomm_II
Цитата Сообщение от otixsom
Зачем вы вообще туда полезли в этот UART_Receive_IT? Это же все до первой генерации кода Кубом. Потом все ваши изменения перетрутся. Эта функция не предназначена для внесения в неё изменений. Правьте USORTx_IRQHomdler или же лучше сделайте как я вам писал выше.
Открою небольшой "секрет" - если исправленные файлы поместить в Репозиторий, то Куб при каждой генерации кода будет их Вам совать сам!!!
Ох мля! (рукалицо)...
Хотя индусы одобрят. Да
0
0 / 0 / 0
Регистрация: 24.08.2009
Сообщений: 3
17.11.2016, 23:30 37
Цитата Сообщение от otixsom
Цитата Сообщение от Yoomm_II
Цитата Сообщение от otixsom
Зачем вы вообще туда полезли в этот UART_Receive_IT? Это же все до первой генерации кода Кубом. Потом все ваши изменения перетрутся. Эта функция не предназначена для внесения в неё изменений. Правьте USORTx_IRQHomdler или же лучше сделайте как я вам писал выше.
Открою небольшой "секрет" - если исправленные файлы поместить в Репозиторий, то Куб при каждой генерации кода будет их Вам совать сам!!!
Ох мля! (рукалицо)...
Хотя индусы одобрят. Да

Полоностью согласен с предыдущим оратором... :) А Ведь советы дельные дали...
0
1 / 1 / 0
Регистрация: 10.09.2015
Сообщений: 171
18.11.2016, 00:14 38
Цитата Сообщение от dosykus_2
Мда, случай тяжелый. Думается вы выходец с AVR, иначе откуда такое уверование?
Уверование в исключительность и непокобелимость калокуба?
Ошиблись, хотя и не далеко - я не выходец с AVR. О себе. С AVR знаком шапочно - только по Ардуине (даже даташит не смотрел), с нее познакомился с электроникой, за что ей (Ардуине) большое спасибо. Четыре года назад я не знал даже как правильно подключить светодиод или кнопку. Программировал последний раз 16 лет назад на Delphi. Три года назад перешел на stm32 - писал на SPL в Coosox. Были большие пробелы в знаниях, сейчас конечно получше, но не настолько хорошо как хотелось бы. Я был незнаком даже с терминологией. Например, не знал чем отличается открытый (и почему он вдруг открытый :-) ) коллектор от пуш-пула, а в Интернете везде об этом говорится как о само-собой разумеющееся. Я понимаю: возьми книгу и прочти. Я читал, но у меня электроника хобби и ею могу заниматься когда уложу детей спать, т.е. с 23.00 по 01.00, а в 06.00 подъем. Поэтому планомерно заниматься некогда, 2 часа не располагают к этому. В результате у меня уходило по часу на разбирательство как подключить какую-нибудь кнопку к микроконтроллеру, на написание программы уходило намного меньше времени. По этой причине 2 года назад даже пришлось вернуться на Ардуину: заканчивал ремонт в новой квартире, пришлось делать контроллер управления освещением на ней - жена убила бы меня, если я не успел бы закончить все к переезду (20т.руб на кнопочные выключатели было уже потрачено).
Потом я наткнулся на mbed.org. Посмотрел... и решил что это уж слишком. После SPL туда... Вот здесь я полностью с Вами согласен
насколько ограничивает
Ушел...
И тут, со второй попытки, я перешел на HAL. В частности из-за того, что у меня появилась Nucleo 411.
Я полностью с Вами согласен, что даташиты (RM) читать нужно. Но из-за незнания языка и ограничения по времени я стараюсь вдумчиво читать те, без которых не обойтись - на подключаемые устройства. RM на stm32 я читал, но поверхностно.
У меня нет
Уверование в исключительность и непокобелимость калокуба
. Я прекрасно осознаю, что твердые знания микроконтроллера позволят использовать его максимально полно. И я стараюсь расширять свои знания. Но HAL и Cube лично мне дали значительную свободу в выборе, того с чем я работаю, особенно в моем ограничении по времени. Сейчас я использую микроконтроллеры 030, 103, 407, 411 (купил, но еще не прибыл ко мне 746), и да, я знаю в чем они отличаются - RM просматриваю. Я знаю, что HAL даст и оверхед, и лишний расход памяти, и скрывая от программиста работу, ограничивает его.
Если мне понадобится низкоуровневая работа с микроконтроллером, я буду ее использовать, но уходить на CMSIS только для супер оптимизации кода не буду - могу выбрать и микроконтроллер пожирнее, благо выбор велик.
Вы меня поражаете (в хорошем смысле слова) своими знаниями микроконтроллеров. Но Ваша точка (именно точка, а не кругозор) зрения по поводу альтернатив меня тоже поражает (уже не совсем в хорошем смысле). Я сейчас "по утрирую". Если следовать Вашей логике, то вокруг нас почти один кал: HAL, RTOS, SPL, C, C++, Wymdows - все они дают оверхед и скрывают от программиста возможности (особенно Wymdows - даже с портами напрямую как в DOS нельзя поработать).
Я не собираюсь далее с Вами спорить "что круче: компот или чай" - каждому свое. Поэтому можете не отвечать, я никого ни в чем не собираюсь переубеждать, и если Вы ответите, то я конечно прочту, но холивар развивать не буду.
0
vosopitrov
14.04.2017, 21:06 39
Доброго дня!
Работаю с STM32F4Dyscovery.
Посмотрел примеры для работы HAL_UART. Запустил прием-передачу:
HAL_UART_Transmit(&huart1, (uint8_t*)buffer, 4, 100);
HAL_UART_Receive(&huart1,(uint8_t*) byte, 1, 1000);
Все работает.

Однако как запустить прием-передачу через прерывание - не понял.
Такая конструкция не работает:
if(HAL_UART_Transmit_IT(&huart1, (uint8_t*)buffer, 4) == HAL_OK)
{
HAL_UART_Receive_IT(&huart1,(uint8_t*) byte,1);
}

В функции HAL_UART_TxCpltCallback и HAL_UART_RxCpltCallback, соответственно, не попадаю.
Пробовал принудительно включать прерывания:
__HAL_UART_ENABLE_IT(&huart1, UART_IT_TXE);
__HAL_UART_ENABLE_IT(&huart1, UART_IT_TC);
__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
Ничего не помогает.

Хотя USORT1_IRQHomdler на что-то реагирует.

Кто-нибудь работал в HAL? Интересует: как правильно подключать?
Поделитесь опытом, пожалуйста.
Подключение без HAL не предлагать, это я и так умею.
Спасибо!
0 / 0 / 0
Регистрация: 08.07.2016
Сообщений: 182
15.04.2017, 09:05 40
и чего я делаю не так? :-)
Пользуюсь HAL-командами для UART. Обычно - через прерывание. Никаких проблем.
Напрягло изначально то, что при приеме надо указывать количество байт. А в моих протоколах оно заведомо неизвестно. Не беда. Принимаю по одному байту и взвожу таймер. По паузе в байтах считаю прием оконченным.

Когда впервые связался с STM32F030, то для него еще Куба и HAL-а не было. Делал ручками, пришлось попрыгать.
Зато сейчас UART у меня во всех STM32 работает одинаково. Одна и та же команда для UART.
0
15.04.2017, 09:05
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
15.04.2017, 09:05
Помогаю со студенческими работами здесь

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

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

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

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

HAL UART, прошу совет
Добрый вечер. Помогите новичку. Пытаюсь соединить два контроллера по uart (второй - авр). STM32f10*...

правильное использование HAL и UART
в структуре инициализации для UART (UART_HomdleTypeDef) есть такие поля uint8_t ...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru