uart interrrupt

19 posts / 0 new
Last post
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I want to set up my AVR to run a program, but if something is ever detected on the UART, it would stop running the program and instead receive data from the UART.

How do I set up this interrupt? Is it possible?

How do YOU make a robot?
http://www.societyofrobots.com

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

Well. All I can tell You is to read:

1. The MCU data sheet
2. The compiler manual
3. Some examples after doing that homework

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

Quote:

Is it possible?

Yes.
Quote:

How do I set up this interrupt?

Depends on what compiler or assembler you use, and on the AVR model you use.

Pseudocode (sketchy):

int UARTflag 0;

InterruptServiceRoutine()
{
   UARTflag = 1;

   // Also handle the incoming character (eg. store it in a variable 
   // so that the code in main can get it and process it further
}

int main(void)
{
   // Set up your UART parameters here

   while (1) {
      if (UARTflag == 0) {
         // Run your initial program here
      }
      else {
         // Run your UART-receiving code here
      }
   }
   return 0;
}

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington]

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

I'm a weak programmer, so I'll need more hints than 'read the datasheet' :shock:

Quote:
Some examples after doing that homework

Know of any? No luck on my not-so-educated search . . . I basically need someone to give me some good hints and links to places to read up on it.

Quote:
Depends on what compiler or assembler you use, and on the AVR model you use.

AVR Studio with gcc, ATmega640. The ATmega640/2560/etc microcontroller seems to be a serious weakness here at avrfreaks.net, because 90% of my questions on it go unanswered . . . AVRlib doesn't even support it, so I've had to rewrite a lot of code . . .

edit: Oh and that pseudocode won't work, as it requires and if statement to check a flag. I however need to jump out of code *immediately* and not wait for a while loop to cycle.

How do YOU make a robot?
http://www.societyofrobots.com

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

Quote:

I'm a weak programmer

Then you need to take small steps: Learn one little simple thing. Then the next. Taking many small steps you will stand a much better chance to get to your goal than trying to take one giant leap.

One, not so small, step would be to get the reception of data on the USART working. So you will need to read the USART ection of the data sheet. You might not understand all of it, but you need to read it so that you have a feeling for when the answer to a question might be in there and it is time for you to return to the data sheet.

You will also need to understand interrupt mechanisms in general, and how they are implemented with avr-gcc.

One obvious complication is that when implementing reception of USART data, how do you know if it is functioning? One way would be to just transmit the received character on the USART again. If you attach your AVR to a serial port on a PC and run a terminal program there you will then be able to type characters that will be echoed back by the AVR ans shown in the terminal program.

Another way would be to display any received character on eight LEDs and still use a PC terminal program to send characters to the AVR.

IIRC there is a USART tutorial in the Tutorial forum. Seek it out!

Might we be enlightened by some more details of the application? This would give us a better chance to give good help. (Or have you come up with the business idea of the century...? :wink: )

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington]

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

You misunderstand what I asked . . .

I have the UART working already. I can read data, arrays, streams, whatever and process it fine. I can easily have my program wait for data in a while loop, too.

The question is, how do I trigger an interrupt to jump my avr out of its currently running program to go into another program. Its not as simple as a timer interrupt or digital pin interrupt.

As you can see in the below pseudocode, the avr is busy calculating and can't just sit in a wait_for_uart_data() loop forever:

while(1)
{
int i;
i++;//avr busy calculating important stuff
}
uart_interrupt(void)
{
receive_uart_data_stream();
}

How do YOU make a robot?
http://www.societyofrobots.com

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

OK, so look in my pseudo-code above. You don't want to have a heavy ISR. Although exceptions can be discussed, generally you want an ISR to do the absolute necessary, in your case get the received character and store it in some intermediary place, and then bail out. Your main program runs in an endless loop, switching between the two tasks (calculating important stuff and dealing with received USART data depending on some variable(s) shared between the ISR and the main program.

It might well be that UART data comes in such a high speed that you will need a buffered solution. The IR stuffs data into a buffer. The main program picks data out of that buffer until it's empty. This way, although the main program might be in the middle of dealing with a character that originated from the USART new incoming data can readily be accepted as it will not overrun elder data. The size and structure of this buffer depends on the incoming data rate, and how heavy processing of that data is.

Search this site, Google etc for "ring buffer".

And again: There is a tutorial in the Tutorial forum on using interrupt driven serial communications. Search it out.

Quote:

Oh and that pseudocode won't work, as it requires and if statement to check a flag. I however need to jump out of code *immediately* and not wait for a while loop to cycle.

That pseudocode is as close as I can get without knowing more about the specific application. The only one knowing more is you, claiming that you need to jump out immediately. This demands a re-write of the "important calculations" part so that it is possible to get out of it immediately, and as you said nothing more than "calculating important stuff" the only thing that can be said is that that code needs to check if it should stop doing what it's doing often enough for it to be able to stop immediately. Whatever that means. In one CPU clock cycle? Before the next character arrives in the USART? Before the moon falls down?

More details on what you are actually trying to do will yield better answers.

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington]

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

Ok I'll better explain what the code is doing.

The code will always be 'calculating important stuff' forever. Non-stop. Until the moon falls down. The time changing results end up as changes on various output pins, but thats not important.

Now the UART data can come at any time (from some other microcontroller or PC). Every 10ms, or even every 10 years - 100% unpredictable. If the avr is in the middle of calculating something important, I don't care, I want it to exit *immediately* and start accepting UART data.

To have it 'calculate something' for 1ms, then check the uart in a while loop, repeat, will not work. It could entirely miss uart data in that 1ms delay.

Quote:

There is a tutorial in the Tutorial forum on using interrupt driven serial communications. Search it out.

I'm looking at it now, and on quick glance it appears to have code in it that I want. I'll report back if I get stuck.
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=48188&highlight=interrupt+driven+uart

How do YOU make a robot?
http://www.societyofrobots.com

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

If you aren't experienced with interrupts and that rot, then have your main program be in a loop that checks the UART status bits to see if a byte has come in. If so, input that byte and either act upon what that byte tells you, or buffer it for later use when the rest of the expected bytes come in.

Of course, you'll need this loop to check at a rate higher than the bytes per second that can arrive, based on your chosen baud rate and other things.

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

Well I'm puzzled. I read this entire thread and I still don't see how the psuedo-code that Johan posted at the start isn't the answer to the "problem"? What I'd probably do is actually disable the RX interrupt as soon as the fist char s received - pass it across to main (in fact it might even be the "flag" itself?) and then continue with polling there once you've switched to "UART mode"

 

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

So the reason to stop immediately is that you don't want to loose data, and nothing else. This is no new problem. You're dealing with a classic.

IMO the way to deal with it is to do jut what I said above: Let the ISR buffer incoming data. It does so *immediately* (as it is an ISR...). The rest of the treatment of incoming data happens in main, where you can allow yourself not to react lightning fast as the data has now been buffered.

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington]

Pages