Electronic – How to read whole data sent to USART with interrupt

avrcinterruptsuart

I am currently able to read byte by byte from USART with this code

ISR(USART_RX_vect)
{
    cli();
    while(!(UCSR0A&(1<<RXC0))){};
    // clear the USART interrupt  
    received = UDR0;

    if(pinState == 0)
    {
        OCR2A = received;
        pinState = 1;
    }
    else if(pinState == 1)
    {
        OCR2B = received;
        pinState = 2;
    }
    else
    {
        OCR0A = received;
        pinState = 0;
    } 
    sei();
}

But now I will send 4 bytes of data which is solely necessary for my application. I could not figure out how to read 4 bytes at once since the interrupt is triggered for every byte. Thank you for any effort in advance.

To make it clearer I will briefly explain what that pinState is. I am sending 3 bytes of data and I want the 1. byte to go pin 3 pwm 2. byte pin 11 pwm and 3. byte to pin6 pwm. As you see in every interrupt I am not gettin 3 bytes, but 1 byte instead. So that pinState thing is only standing for that purpose.

Best Answer

You did not mention which microcontroller you are using, but it probably doesn't matter. USART peripherals generally operate exactly as you have discovered: one byte at a time. This, however, is not a limitation.

Based on the code snippet you posted in your question, you're trying to execute some functionality with every received byte. That limits you to one-byte operations. What if, instead, you used the ISR just to populate an array of bytes? Then, after a certain number of bytes had arrived, only then do you read the bytes and interpret their meaning - preferably in the main loop of your code, not the ISR.

Be careful of doing too much work in an ISR. Especially calling functions from within the ISR function. Every silicon manufacturer and compiler is different, of course, but calling functions within ISRs can often lead to extremely slow, inefficient code. The majority of your computations and data handling should happen in your main loop. ISRs should be used for setting flags and quick operations. You generally want to exit the ISR as quickly as you can.