Electronic – Best way to find delay between receive data from USART

atmegauart

I write a code (for Atmega168P) for receive data from USART interrupt as below:

ISR     (USART_RX_vect)
{
    unsigned char count=0;      
    unsigned char coder[13];    
    int over_uart=0;

    for (count=0;count<13;count++)
    {
        while (!recive_485)
        {
            over_uart++;                
            wdt;
            if (over_uart>=20000)   {   
                coder[0]=0;     
                count=14;       
                over_uart=0;    
                break;  }
        }
        coder[count]=UDR0;
    }
}

Each time that i receive 13 byte of data and put in coder array.

I use a variable over_uart for calculate time between each of received byte. if over_uart>=20000, means that:

The receive progress is start but we have problem in lines that do not get next byte in 20000ms And terminate the last command and look for new 13byte that will receive from line.

Any body know a optimized way that find delay between receive data from USART (without help of over_uart variable)?

EDIT:

I correct the problem in my code and remove put delay in ISI as blow:

ISR     (USART_RX_vect)
{
    coder[count]=UDR0;
    if (coder[count] == 20)
        UartFlag=True;
    else
        count++;
}

And in Main function:

while (1)
    {
        if (UartFlag)
        {
            DoSomthing();
            count=0;
            UartFlag=Fulse;
        }
    }

Best Answer

Realize that interrupt routine is only the code to be jumped into, nothing more. So, your code totally a misunderstatement:

  • Your most variables there must be static. In your code they are stacked locals which are recreated at every interrupt. Also because of undetermined code flow caused by interrupts, you have to disable possible optimizations on vulnerable variables by declaring them as "volatile".

  • Don't make that kind of loops there. Realize that every interrupt etrance is the part of data collecting loop.

To solve the problem, your best shot is using a hardware timer. At every interrupt etrance, take a reading from a timer which is reset by the previous interrupt's exit code. So, you can easily determine if there is a overflow and take care of it.