Skip to main content
Graduate II
February 18, 2022
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.

  • February 18, 2022
  • 4 replies
  • 2380 views

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.

    4 replies

    Super User
    February 18, 2022

    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.1Author
    Graduate II
    February 18, 2022

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

    -Thanks & Regards

    Hrishikesh

    Graduate II
    February 18, 2022

    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.1Author
    Graduate II
    February 19, 2022

    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

    Super User
    February 19, 2022

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

    hth

    KnarfB

    Graduate II
    February 18, 2022

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