2019-11-30 04:49 PM
Hi, I'm trying to use HAL_UART_Receive_IT with a fixed size buffer, but only the first element changes its value.
I'm using CubeMX over NUCLEO-STM32F446RE
The only things I do:
main.c
I declare the buffer like this:
uint8_t rx_buffer[5];
The UART initilization:
static void MX_USART2_UART_Init(void)
{
/* USER CODE BEGIN USART2_Init 0 */
/* USER CODE END USART2_Init 0 */
/* USER CODE BEGIN USART2_Init 1 */
/* USER CODE END USART2_Init 1 */
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART2_Init 2 */
/* USER CODE END USART2_Init 2 */
}
and inside the main function, just before the while loop:
HAL_UART_Receive_IT(&huart2, rx_buffer, sizeof(rx_buffer));
stm32f4xx_it.c
I declare the extern variable:
extern uint8_t rx_buffer[5];
and the ISR:
void USART2_IRQHandler(void)
{
/* USER CODE BEGIN USART2_IRQn 0 */
/* USER CODE END USART2_IRQn 0 */
HAL_UART_IRQHandler(&huart2);
/* USER CODE BEGIN USART2_IRQn 1 */
HAL_UART_Receive_IT(&huart2, rx_buffer, sizeof(rx_buffer));
/* USER CODE END USART2_IRQn 1 */
}
stm32f4xx_hal_msp.c
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(huart->Instance==USART2)
{
/* USER CODE BEGIN USART2_MspInit 0 */
/* USER CODE END USART2_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_USART2_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
GPIO_InitStruct.Pin = USART_TX_Pin|USART_RX_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USART2 interrupt Init */
HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART2_IRQn);
/* USER CODE BEGIN USART2_MspInit 1 */
/* USER CODE END USART2_MspInit 1 */
}
}
I'm using Docklight to transmit the characters 'abcde' but debugging and watching rx_buffer,
only the first element changes, 'a', the rest remains to '\0' and therefore HAL_UART_RxCpltCallback is never called, the ultimate objective.
What's wrong with my code? Thanks!
2019-12-01 03:14 AM
The HAL_UART_Receive_IT() in interrupt handler restarts the reception...
2019-12-01 04:43 AM
Don't use HAL function inside the IT.
Just read your incoming data byte, put in your buffer and increase the index for the next come back byte.
There should be some nucleo project uart examples in cube.
2019-12-01 09:55 AM
I've seen that if not in the interrupt handler, the ISR was called just the first time I transmit data because of the initial HAL_UART_Receive_IT of the main function and never again.
I guess HAL_UART_Receive_IT() should be inside the callback, but the callback never gets called.
2019-12-01 10:43 AM
I think that makes sense but then I don't understand why HAL_UART_Receive_IT() needs the size of the buffer if I have to go byte by byte.
The problem also is that the IRQHandler is called just once, it changes the first element of the buffer and then nothing... How could I read the different incoming data with just one iteration?