Skip to main content
wbarkley
Associate III
September 13, 2012
Question

USART1 interrupt issues, seems to get stuck after 2 or 3 triggers...

  • September 13, 2012
  • 11 replies
  • 2549 views
Posted on September 13, 2012 at 16:12

The original post was too long to process during our migration. Please click on the attachment to read the original post.
    This topic has been closed for replies.

    11 replies

    Tesla DeLorean
    Guru
    September 13, 2012
    Posted on September 14, 2012 at 01:40

    You need to stop doing the while() loops and SendString functions under interrupt, they will soak up way too much time, causing data in the in bound USART to overrun. You might also need to consider checking for, and clearing, USART errors.

    Your interrupt routine should look more like this.

    unsigned char rxData[4];
    uint8_t rxDataCount = 0;
    void USART1_IRQHandler(void)
    { 
    if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
    {
    rxData[rxDataCount++] = USART_ReceiveData(USART1);
    if (rxDataCount >= sizeof(rxData)) rxDataCount = 0;
    }
    }

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    wbarkley
    wbarkleyAuthor
    Associate III
    September 14, 2012
    Posted on September 14, 2012 at 20:20

    The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6lX&d=%2Fa%2F0X0000000bus%2FlX9r2H2EBoeGjlYmI3q4iXJpLhVhlvpytwAyYOhI9fU&asPdf=false
    wbarkley
    wbarkleyAuthor
    Associate III
    September 14, 2012
    Posted on September 14, 2012 at 22:07

    The exact order of actual info when buffer is increased to 6 instead of 4 is:

    13, 10, 51, 45, 48, 57

    Tesla DeLorean
    Guru
    September 14, 2012
    Posted on September 14, 2012 at 22:21

     I would also like some pointers to see if there is a better way to handle the sending of data then what I am currently doing (through interrupt, by checking certain flags, handling the tx execution differently).

    You need to implement some FIFO (ring/circular) buffers, which separate the foreground function of stuffing characters/strings into the buffer, and the background (interrupt) routine which deals with the byte going to the USART.

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    wbarkley
    wbarkleyAuthor
    Associate III
    September 17, 2012
    Posted on September 17, 2012 at 14:47

    Any ideals on my receive issues?

    Tesla DeLorean
    Guru
    September 17, 2012
    Posted on September 17, 2012 at 17:16

    Any ideals on my receive issues?

     

    Not really, I don't know the nature of the data stream you expect to be receiving. If you are expecting multiple bytes you going to have to figure out how to store and process that data, and resynchronize the stream if it starts mid sequence.

    10, 13 is suggestive of a <CR> <LF> end of line markers, in which case you should design your code to parse/process lines of data, and restart when you get a new line.

    Also be aware that a 16-bit unsigned value is never going to be bigger than 65535, so testing for that condition isn't going to be helpful.

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    wbarkley
    wbarkleyAuthor
    Associate III
    September 17, 2012
    Posted on September 17, 2012 at 17:51

    intTimes = 32 when the receive interrupt stops.  Doesn't this mean there was 32 bits received thus 4 chars worth of info - the 48, 57, 13, 10?  So why when just the buffer size increases to 6 I get values for RxBuffer[4] and RxBuffer[5] when intTimes remains at 32?  It seems as though RxBuffer[4] and RxBuffer[5] should remain at their original values since the interrupt did not execute more than 32 times.

    void USART1_IRQHandler(void)

    {    

        //Receive Interrupt Handler

        if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){

            intTimes++;

            if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){

                RxBuffer[RxCount++] = USART_ReceiveData(USART1);

                if (RxCount >= sizeof(RxBuffer)) RxCount = 0;

            }

        }   

    }

    wbarkley
    wbarkleyAuthor
    Associate III
    September 17, 2012
    Posted on September 17, 2012 at 18:06

    intTimes = 32 when the receive interrupt stops.  Doesn't this mean there was 32 bits received thus 4 chars worth of info - the 48, 57, 13, 10?  So why when just the buffer size increases to 6 I get values for RxBuffer[4] and RxBuffer[5] when intTimes remains at 32?  It seems as though RxBuffer[4] and RxBuffer[5] should remain at their original values since the interrupt did not execute more than 32 times.

    Tesla DeLorean
    Guru
    September 17, 2012
    Posted on September 17, 2012 at 19:09

    The interrupt does not occur on a bit basis. In the case of the receive it occurs when a framed byte (start, 8 bits, stop) enters the holding buffer.

    If the interrupt has occurred 32 times, you need a significantly larger buffer to hold the incoming data.

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    michaelmccartyeng
    Associate III
    September 18, 2012
    Posted on September 18, 2012 at 03:31

    realize that with your current code when you overrun your buffer you will end up writing back to the begging. if you have an expected packet structure it will destroy at least one packet causing you to loose data. 

    You should look into a circular buffer or at least be sure not to set the rxbyte count back to 0 anywhere else except in the int and check for overflow. I only say this because I ran into the same issue with the exact same code. I would get errors at high bit rates and eventually found out it was because upon sending two packets my buffer was getting set back to index 0 and destroying my packet, but only if sending two at a time. 

    Circular buffers might have a little learning curve but they are a great way to handle this sort of situation.