cancel
Showing results for 
Search instead for 
Did you mean: 

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.

HDesa.1
Senior

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;

}

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

-Regards
Hrishikesh
7 REPLIES 7
KnarfB
Principal III

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
Senior

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

-Thanks & Regards

Hrishikesh

-Regards
Hrishikesh
MM..1
Chief III

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

Piranha
Chief II

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

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

-Regards
Hrishikesh

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

hth

KnarfB

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 ...