2024-03-21 07:28 AM
Hello,
I am trying to use USART peripheral of my STM32F303VCT6 based board.
I want to receive the data on serial line and size of the data is not fixed or known beforehand. Once the particular string of data is received, I compare it with predefined strings stored in various arrays & based on the match, which of the if/else codes in while loop should be implemented, is decided.
In the If/else code, I also want to receive the data from same USART but this data is not to be used for the comparison above & length of this data is known. Once If/else code is executed, program should again wait for new string for comparison.
For this, I have used HAL_UARTEx_ReceiveToIdle_IT & HAL_UART_Receive as given in the code snippet below,
Callback Function is -
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
FS1State=memcmp((uint8_t *) globalRxBuff,FS1,sizeof(FS1));
FS2State=memcmp((uint8_t *) globalRxBuff,FS2,sizeof(FS2));
FS3State=memcmp((uint8_t *) globalRxBuff,FS3,sizeof(FS3));
FS4State=memcmp((uint8_t *) globalRxBuff,FS4,sizeof(FS4));
if(FS1State==0)
{
page=1;
}
else if(FS2State==0)
{
page=2;
}
else if(FS3State==0)
{
page=3;
}
else if(FS4State==0)
{
page=4;
}
memset((uint8_t *) globalRxBuff,0x00,27);
HAL_UARTEx_ReceiveToIdle_IT(&huart2, (uint8_t*)globalRxBuff, 100);
}
While loop -
while(1)
{
if(page==1)
{
CLEAR_BIT(huart2.Instance->CR1,USART_CR1_RXNEIE); //Disabling the RXNE Interrupt
CLEAR_BIT(huart2.Instance->CR1,USART_CR1_IDLEIE); // Disabling the Idle Line Interrupt
huart2.RxState= HAL_UART_STATE_READY;
HAL_UART_Transmit(&huart2,txBuff,10,HAL_MAX_DELAY);
HAL_UART_Receive(&huart2, page1RxBuff, 6, HAL_MAX_DELAY);
SET_BIT(huart2.Instance->CR1,USART_CR1_RXNEIE);
SET_BIT(huart2.Instance->CR1,USART_CR1_IDLEIE);
}
else if(page==2)
{
CLEAR_BIT(huart2.Instance->CR1,USART_CR1_RXNEIE); //Disabling the RXNE Interrupt
CLEAR_BIT(huart2.Instance->CR1,USART_CR1_IDLEIE); // Disabling the Idle Line Interrupt
huart2.RxState= HAL_UART_STATE_READY;
HAL_UART_Transmit(&huart2,txBuff,10,HAL_MAX_DELAY);
HAL_UART_Receive(&huart2, page2RxBuff, 6, HAL_MAX_DELAY);
SET_BIT(huart2.Instance->CR1,USART_CR1_RXNEIE);
SET_BIT(huart2.Instance->CR1,USART_CR1_IDLEIE);
}
else if(page==3)
{
CLEAR_BIT(huart2.Instance->CR1,USART_CR1_RXNEIE); //Disabling the RXNE Interrupt
CLEAR_BIT(huart2.Instance->CR1,USART_CR1_IDLEIE); // Disabling the Idle Line Interrupt
huart2.RxState= HAL_UART_STATE_READY;
HAL_UART_Transmit(&huart2,txBuff,10,HAL_MAX_DELAY);
HAL_UART_Receive(&huart2, page3RxBuff, 6, HAL_MAX_DELAY);
SET_BIT(huart2.Instance->CR1,USART_CR1_RXNEIE);
SET_BIT(huart2.Instance->CR1,USART_CR1_IDLEIE);
}
else if(page==4)
{
CLEAR_BIT(huart2.Instance->CR1,USART_CR1_RXNEIE); //Disabling the RXNE Interrupt
CLEAR_BIT(huart2.Instance->CR1,USART_CR1_IDLEIE); // Disabling the Idle Line Interrupt
huart2.RxState= HAL_UART_STATE_READY;
HAL_UART_Transmit(&huart2,txBuff,10,HAL_MAX_DELAY);
HAL_UART_Receive(&huart2, page4RxBuff, 6, HAL_MAX_DELAY);
SET_BIT(huart2.Instance->CR1,USART_CR1_RXNEIE);
SET_BIT(huart2.Instance->CR1,USART_CR1_IDLEIE);
}
HAL_UART_Receive_IT(&huart2, (uint8_t*)globalRxBuff, 100);
}
This code above sometimes work and sometimes it does not trigger the callback function.
At the time when it is not working, it is stuck in HAL_UART_IRQHandler function & when I go through the code step by step in debug mode, at some point it gets back into the while loop & starts working again.
Has anyone else experienced such issue?
Is there any problem in the code above?
Desperately in need of help!
Thanks in Advance..
2024-03-21 07:41 AM
This is a Very Frequently Asked Question.
Short answer: HAL_UARTEx_ReceiveToIdle_IT is not convenient to use as-is in most real life cases. Either use other functions, especially circular DMA - HAL_UARTEx_ReceiveToIdle_DMA - or roll your own.