Skip to main content
HDesa.1
Associate III
Feb 18, 2022 7:45 AM UTC
Question

I am trying to run UART on STM32 MCU using HAL library for one of my application. I would like to receive packet of data which I am not able to do. Can you please guide me in this? I have provide details below.

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;

}

****************************************************************************************************

This topic has been closed for replies.

7 replies

KnarfB
Super User
Feb 18, 2022 8:28 AM UTC

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

HDesa.1
HDesa.1Author
Associate III
Feb 18, 2022 8:33 AM UTC

Thank you KnarfB for your suggestion. I will try this method.

-Thanks & Regards

Hrishikesh

-RegardsHrishikesh
MM..1
Super User
Feb 18, 2022 2:14 PM UTC

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);
}

HDesa.1
HDesa.1Author
Associate III
Feb 19, 2022 6:09 AM UTC

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

-RegardsHrishikesh
KnarfB
Super User
Feb 19, 2022 6:42 AM UTC

Then try the other methods suggested. Searcgh for "hal uart receive idle dma". These are used in many projects.

hth

KnarfB

Piranha
Principal III
Feb 18, 2022 11:48 PM UTC

In topic author's code iRxFlag variable must be volatile.