Uart Interrupt read and analyse

Go To Last Post
4 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi, all.
using Atmega128 @8MHz, Winavr, C

I have an application where serial data is coming randomly @4800bps each message is around 100bytes. and 5 messages per second may be the interval.

I am using the Rx interrupt to catch the data and store in a global buffer[100]

ISR(USART0_RX_vect)
{
//if buffer_full_flag is clear
  {
  //if received message is less than 100{ take the   byte and incr buffer}
  // if buffer ==100
  // set buffer_full_flag
  }
}

I clear the buffer_full_flag in my main so as to receive again.

Now my challenge is I have to compare this 100byte message with my already existing messages [maybe 50] and do the necessary action.

All this has to be done without missing the main functions action, which is to display time on 7 segment - incrementing every second[using timer interrupt].

i think this can be done.
But I am not sure how much time each instruction will take and if i will miss the display on 7 segment. or will the system hang.

pls give me some inputs how to go about this task.

Secondly, example I am in ISR(USART0_RX_vect), suddenly timer ISR SIGNAL(SIG_OUTPUT_COMPARE1A) fires, since its priority is more it will go into that ISR and after finishing the ISR does it go to main or come back to this Rx ISR(USART0_RX_vect) and continue from where it left ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you want to know the timings -- calculate them using assembler output from gcc and instruction tables. AVR core is in-order and the timing is pretty straightforward.

To do it in a simple way, calculate how many basic operations (additions, comparisons, assigns) you have in your loops and assume that you spend 1 clock per each op (which is, of course, not true but valid for first-order approximation).

Kind regards,
Dmitry

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Unless you specifically enable it, an interrupt cannot interrupt an ISR, but rather the new ISR will run immediately after the current ISR finishes (this is why, except in rare circumstances, all ISRs should be short and quick).

As to missing your 7-seg (multiplexing?) operation, that won't happen. At worst you may be a few microseconds late in servicing the timer interrupt, but it will get serviced.

A few timing numbers: @4800 baud, you will receive a uart interrupt about every 2ms. You will also have a multiplexing timer interrupt every 1 or 2 ms. Assuming your uart ISR runs in a few microseconds, and your mux timer interrupt in a few 10s of microseconds, you can see that your system will be plenty responsive, and can spend most of its time processing the messages. You should be fine.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Regarding your UART interrupt.

Most regular (i.e. non AVRFreak) implementations will use a circular RX buffer.

With a buffer size of say 128 bytes, you will have 266 ms to deal with any processing. So your mainline code really has no worries at all of ever missing any bytes.

e.g. you just call getchar() as required. The multiplex looks after itself. The RX looks after itself.

This does all depend on using regular common sense.
1. no busy-wait loops in ISR()s
2. no calls of functions that busy-wait.
3. no SEI() in ISR()s
4. no resetting of buffer pointers by mainline code.

Anathema to most of the examples seen here. Standard practice in PCs, microcontrollers, the rest of the civilised world ...

David.