2022-02-17 11:45 PM
I have created an application where I can transmit and receive data over UART port one by one. I am also able to receive packets in sets where I know the size of the data.
But in my case, I want to receive data packet of unknown length and read from receive buffer one by one which I am not able to do. When I send a packet of data using serial terminal, UART function only reads the first character and then ignore the remaining.
I have added the code segment for the reference below. The code compiles correctly and is working. It's only when I send a packet "Hello" from the terminal(real term), the code reads only 'H'. In my application the packet size varies, hence I can't mention fixed size in function HAL_UART_Receive_IT.
-Regards
Hrishikesh
****************************************************************************************************
int iRxFlag = 0;
int main(void)
{
char cData;
HAL_Init();
MX_GPIO_Init();
MX_UART4_Init();
while(1)
{
if(iRxFlag)
{
iRxFlag = 0;
HAL_UART_Transmit(&huart4, (uint8_t*)&cData, 1, 1);
}
HAL_UART_Receive_IT(&huart4, (uint8_t*)&cData, 1);
HAL_Delay(250);
}
return 0;
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
iRxFlag = 1;
}
****************************************************************************************************
2022-02-18 12:28 AM
You can call HAL_UART_Receive_IT again at the end of HAL_UART_RxCpltCallback.
But: since it all goes through HAL (=takes time)you risk missing input characters.
You will be better off by using the idle interupt, see https://community.st.com/s/feed/0D53W00001AzphUSAR or using DMA as an input FIFO and read at your own pace.
See https://github.com/MaJerle/stm32-usart-uart-dma-rx-tx
hth
KnarfB
2022-02-18 12:33 AM
Thank you KnarfB for your suggestion. I will try this method.
-Thanks & Regards
Hrishikesh
2022-02-18 06:14 AM
Your code is bad BAD
//this must be global for IT not in func or main
volatile uint8_t cData[2]; //better is bigger buff here used only 1 byte
HAL_UART_Receive_IT(&huart4, cData, 1);
//started first byte wait read
while(1)
{
if(iRxFlag)
{
iRxFlag = 0;
HAL_UART_Transmit(&huart4, cData+1, 1, 1);
}
}
return 0;
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
iRxFlag = 1;
//better is copy to protect overwrite
cData[1]=cData[0];
HAL_UART_Receive_IT(&huart4, cData, 1);
}
2022-02-18 03:48 PM
In topic author's code iRxFlag variable must be volatile.
2022-02-18 10:09 PM
Thank you for your suggestion. I had also tried this method.
The method which you had suggested works when time between the 2 data is long. In case, where the entire packet is to be read, this method doesn't work. Also in my case, my packet length is unknown.
-Regards
2022-02-18 10:42 PM
Then try the other methods suggested. Searcgh for "hal uart receive idle dma". These are used in many projects.
hth
KnarfB
2022-02-19 01:34 AM
My code is only example and ofcourse cant work for stream data read and transmit in one time.
In case, where the entire packet is to be read
your words then do it ...