cancel
Showing results for 
Search instead for 
Did you mean: 

I am having difficulty receiving data on USART2. It is receiving one character when I use HAL_UART_Receive_IT interrupts. I am trying to receive some characters from ADUCM360 USART.

cjaya.1
Associate II

I can see transmitting characters from ADUCM360 to STM32.But it does not capture the incoming characters from STM32 using interrupts. Any help on this very much appreciated. Thank you

18 REPLIES 18

Most STM32 have one interrupt per character.And then selectively call-back once the whole request is serviced.

Would suggest managing in-bound data into your own buffers, to handle later, and resubmit the receive requests.

The HAL is a bit of an ugly mess in this regard. Avoid doing any complex or blocking work in the interrupt handlers, or the call-backs they call.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Thank you for the reply.

"Most STM32 have one interrupt per character.And then selectively call-back once the whole request is serviced"

How do I do that because I can see only character on the STM32 data register when it is in interrupt service routine (UARTHandler) before the call back.

cjaya.1
Associate II

also, I try using HAL_UART_Receive_DMA but its still receiving one character when I call it.

You've basically posted the same question 3 times, and not identified what STM32 you're talking about, there's like a hundred at this point.

Don't view the peripheral in the debugger, it reading the data register will clear the status.

If you get an overrun you need to clear that, perhaps look at the Reference Manual for the part you're using.

For an STM32L0 notionally

  if (USART_RS232->ISR & USART_ISR_ORE) // Overrun Error
    USART_RS232->ICR = USART_ICR_ORECF;
  if (USART_RS232->ISR & USART_ISR_NE) // Noise Err
    USART_RS232->ICR = USART_ICR_NCF;
  if (USART_RS232->ISR & USART_ISR_FE) // Framing Error
    USART_RS232->ICR = USART_ICR_FECF;

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Thank you for the reply. I am still having problem. Like you said I am clearing out the Overrun error by reading the DR. I am using STM32F405RGT6 device but I couldnt find any reference material how to clear the Overrun error.

So on the USART2_IRQHandler, this is my code

void USART2_IRQHandler(void)
{
  uint32_t status = USART2->SR;
 
if(status & USART_SR_RXNE)
  {
  c = USART->DR;
  
  if( i < 30)
   Receive[i++] = c;  
  }
else if (status & USART_SR_ORE)
  {
  c = USART->DR;
  if( i< 30)
  Receive[i++] = c;
 CountRx2Overrun++;
  }
}

Can you point to me what I am doing wrong. Thank you

EEbyKarl
Associate III

You need to call HAL_UART_Receive_IT() after each interrupt after you read the character out of the register, which then enables interrupt again for the next character.

Thank you for the reply. So on the USART2_IRQHandler() inside, I should call back HAL_UART_Receive_IT(). Is that right?

Yes, that is correct.

Thank you for the reply. I am still having problem with it. I am able to receive some data. but it is looks like the same data. it needs to be change. Can you see any problem with this code?

    void USART2_IRQHandler(void)
    {
      uint32_t status = USART2->SR;
     
    if(status & USART_SR_RXNE)
      {
       ch = USART->DR;
       if(ch != '\n')
         {
         Receive[i++] = (uint8_t*)ch; 
          }
       else
         {
          i = 0;
          }
       USART2->SR &= ~USART_SR_RXNE;
       USART2->CR3 &= ~USART_CR3_EIE;
       }
    else if (status & USART_SR_ORE)
      {
      ch = USART->DR;
      if( i< 30)
      Receive[i++] = ch;
     CountRx2Overrun++;
      }
   HAL_UART_Receive_IT(&huart2, (uint8_t*)ch, 1); 
   HAL_UART_IRQHandler(&huart2);
    }