#c #stm32 #cortex-m #infrared #usart
#c #stm32 #cortex-m #инфракрасный #usart
Вопрос:
Я пытаюсь получить некоторые данные с помощью USART в режиме IrDA на плате STM32H7 с драйверами HAL.
Я получаю ожидаемый ответ на выводе gpio (скорость передачи в бодах, логика и синхронизация в порядке), но по какой-то причине данные никогда не перемещаются в регистр RDR USART, и когда я пытаюсь их прочитать, я просто получаю нули с первой попытки и тайм-аут после этого (режим опроса).
После заполнения структуры дескриптора IRDA я вызываю HAL_IRDA_DeInit()
и HAL_IRDA_Init()
. Я настраиваю GPIO в HAL_IRDA_MSP_Init()
и отправляю первое сообщение, которое достигает цели (с помощью HAL_IRDA_Transmit()
). Затем цель отправляет ответ, который я могу проверить по pin-коду UART_RX. И здесь что-то происходит.. или лучше не происходит. Если я прочитаю UART с HAL_IRDA_Receive()
(по 1 байту за раз) Я получаю только ноль, а затем тайм-ауты.
IRDA_HandleTypeDef hirda4;
void vIrdaInit(void)
{
hirda.Instance = USART3;
hirda.Init.BaudRate = 60100;
hirda.Init.WordLength = IRDA_WORDLENGTH_9B;
hirda.Init.Parity = IRDA_PARITY_NONE;
hirda.Init.Mode = IRDA_MODE_TX_RX;
hirda.Init.Prescaler = 1;
hirda.Init.PowerMode = IRDA_POWERMODE_NORMAL;
/* Initialize the IRDA registers. Here also HAL_IRDA_MspInit() will be called */
if (HAL_IRDA_Init(amp;hirda4) != HAL_OK)
{
Error_Handler();
}
}
/* Initialize IrDA low level resources. This function is called by HAL_IRDA_Init() */
void HAL_IRDA_MspInit(IRDA_HandleTypeDef* irdaHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(irdaHandle->Instance==USART3)
{
/* UART4 clock enable */
__HAL_RCC_USART3_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**UART4 GPIO Configuration
PB10 ------> USART3_RX
PB11 ------> USART3_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF7_UART3;
HAL_GPIO_Init(GPIOB, amp;GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
HAL_GPIO_Init(GPIOB, amp;GPIO_InitStruct);
}
}
здесь выполняется вызов HAL_IRDA_Transmit()/HAL_IRDA_Receive():
if(HAL_IRDA_Transmit(amp;hirda (uint8_t*)TxBuf, sizeof(RxBuf), 5000)!= HAL_OK)
{
Error_Handler();
}
memset(RxBuf, '', sizeof(RxBuf));
for (i = 0; i < 8; i )
{
// blocks here until timeout or data
if(HAL_IRDA_Receive(amp;hirda, (uint8_t*)RxBuf, 1, 500)!= HAL_OK)
{
Error_Handler();
}
}
При первом запуске цикла у меня поднят флаг RXNE, но в RDR есть только 0. Следующие итерации всегда приводят к таймауту (от IRDA_WaitOnFlagUntilTimeout()
). Я понятия не имею, где искать… Импульсы, которые я получаю, больше, чем 3/16 периода, уровни в порядке, но, похоже, я не могу получить сообщение через декодер приема SIR и в регистре данных.
ОБНОВЛЕНИЕ: вот скриншот с принятым сигналом:
Скорость передачи в бодах в норме, присутствуют стартовые и стоповые биты, и сообщение (9 бит) — это то, чего я жду. Но не распознается декодером и не передается UART.
Ответ №1:
Добавление фиктивного чтения в 1 байт сразу после вызова функции init позволило мне успешно прочитать один раз без тайм-аутов. Проблема в том, что после этого Receive()
функция снова начинает возвращать тайм-ауты. Единственное обходное решение, которое я смог найти, это повторно инициализировать UART непосредственно перед вызовом Receive()
функции. Это позволяет мне получить полное сообщение. Это неаккуратно, но это работает.
Я пытался найти регистры, которые изменяются, но мне не удалось определить, что вызывает проблему.