Skip to main content
freya17365
Associate III
November 4, 2015
Question

USART1 interrupt

  • November 4, 2015
  • 5 replies
  • 979 views
Posted on November 04, 2015 at 19:42

Hi to all,

I am encountering a problem using USART1 interrupt.

I can correctly send data on tx line and I woul like to use interrupt to receive data from rx line.

I enabled RXNEIE bit in CR1 and created the handler

extern ''C'' void USART1_IRQHandler() // I am using C++

{

    myled.LedOn(LED4);

    Delay(1000);

    myled.LedOff(LED4);

    return;

}

but nothing happened. Do I have to enable something else?

Thank you

Freya

    This topic has been closed for replies.

    5 replies

    Tesla DeLorean
    Guru
    November 4, 2015
    Posted on November 04, 2015 at 20:03

    Do I have to enable something else?

    The NVIC?

    You also need to actually clear the source of the interrupt otherwise it will keep re-entering. I don't like the delays, but you might want one after both LED changes, otherwise the re-entry will just glitch it.

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    shawn2
    Associate II
    November 4, 2015
    Posted on November 04, 2015 at 21:52

    What baudrate and which board?  USART1 is a bit wonky on a few of them.

    May wanna try a different USART.

    freya17365
    Associate III
    November 9, 2015
    Posted on November 09, 2015 at 08:46

    Indeed it is not my goal to switch a led on in the interrupt routine, it was only a test to check if I entered in the toutine.

    What I need is, every time a new charcater arrives, catch it and put it in an buffer for futher elaboration.

    More or less the routine is like this:

    =====================================================

    extern ''C'' void USART1_IRQHandler()

    {

        myusart.PrintString((uint8_t *) ''\n\nUSART INTERRUPT\n'', 0);    // I am entering in the routine

        

        if(USART1->ISR & USART_ISR_RXNE)

        {

            if(iocnt < 500)

            {

                if(c != '\n')

                {

                    iobuf[iocnt++] = c;

                    iobuf[iocnt] = 0;

                }

                else

                {

                    iobuf[iocnt] = 0;    // redundant instruction

                    iocnt = 0;

                }

            }

        }

        

    //    USART1->RQR |= 0x00000008;    

        USART1->ICR = 0x00020A5F;

        return;

    }

    =====================================================

    Enabling NVIC interrupt is working, but still I encounter some problems:

    - Interrupt bit should clear when I read ISR register, but it doesn't

    - Interrupt bit should clear when I set RXRFQ bit in RQR register, but it doesn't

    The only way I found to clear interrupt is to set bits in ICR register and, furthermore, only the first carachter of input string is read.

    Do I have to increase sysclock frequency?

    (it is sysclock = 8 MHz  and baud rate = 115200)

    Thank you

    Freya

    Tesla DeLorean
    Guru
    November 9, 2015
    Posted on November 09, 2015 at 14:15

    Interrupt bit should clear when I read ISR register, but it doesn't

    Are you sure, most STM32 this only occurs if you read the DR or RDR

    Using printf in an interrupt is likely to block for several hundred thousand cycles.

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    freya17365
    Associate III
    November 13, 2015
    Posted on November 13, 2015 at 08:16

    Hi to all,

    I didn't inhibit overrun interrupt and that caused the infinite loop.

    Then I slowed baud rate down to 19200 and deleted all debug lines (that is a lot of printf())  and now it works both on USART1 and USART2.

    Thank you very much

    Freya