Pages: [1]   Go Down
Author Topic: Interrupt for USART RX on Atmega328p seems not to fire  (Read 1431 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 38
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I just want to toggle an LED when the USART finishes receiving, so I wrote the following for the USART_RX_vect, but the LED never changes. However, the LED does toggle if move the code from the ISR into the main loop and precede it with while ( !(UCSR0A & (1<<UDRE0)) );

Can anyone describe my error to me?

Code:
#define F_CPU 16000000UL
#define UBRR_VALUE 416 // baudrate 2400
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

ISR(USART_RX_vect)
{
  char data = UDR0;
  PORTB ^= (1 << PB0); // Toggle the LED
  _delay_ms(500);
}

int main()
{
  DDRB |= (1 << PB0); // Set LED as output

  // Set baud rate
  UBRR0H = (uint8_t)(UBRR_VALUE>>8);
  UBRR0L = (uint8_t)UBRR_VALUE;
  // Set frame format to 8 data bits, no parity, 1 stop bit
  UCSR0C |= (1<<UCSZ01)|(1<<UCSZ00);
  //enable reception and RC complete interrupt
  UCSR0B |= (1<<RXEN0)|(1<<RXCIE0);
  //  Enable global interrupts
  sei();
  
  while (1)
    ;
}

Thank you for your assistance.
« Last Edit: February 02, 2013, 05:15:46 pm by Vaselinessa » Logged

0
Offline Offline
Shannon Member
****
Karma: 206
Posts: 12092
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You are calling delay in an interrupt routine - nothing can happen during that delay and you'll muck up
the millis() clock completely.

Never call delay() in an interrupt routine.
Logged

[ I won't respond to messages, use the forum please ]

Offline Offline
Newbie
*
Karma: 0
Posts: 38
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks. That's instructive.
« Last Edit: February 02, 2013, 07:26:29 pm by Vaselinessa » Logged

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12631
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Is there some other issue I'm failing to recognize?

(As before, if I put this code in the main loop instead of in an ISR, it executes as I expect: the LED is illuminated.)

(That was going to be my first question - is the port manipulation coded correctly? Seems you have proved it is.)

Have you proved that the interrupt handler is executing? (For example you could change a volatile global and then detect and report that change in loop.)
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Offline Offline
Newbie
*
Karma: 0
Posts: 38
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hardware issue. My jumper wire was not quite seated in the breadboard!

Thank you much.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Dear Sir, I'd red your post of "Interrupt for USART RX on Atmega328p seems not to fire", and i can understand the things you do with your code. But sir, Do you use this code with Arduino IDE ? i.e: Is Arduino support main() function? and another thing is that, inside the main function what you do with sei() funtion?

Code:
UCSR0C |= (1<<RXEN0) | (1<<RXCIE0);
sei();
while(1);
 

There is no definition for sei(); function in your code. Do you have the definition for this function in other file. Or else is it a pre-defined One? Please explain what this function do? Thanks in advance.
Logged

UK
Offline Offline
Tesla Member
***
Karma: 121
Posts: 6980
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

sei() is the opposite of cli(). sei() sets the interrupt enable bit in order to allow interrupts to work. It's a built in function.

...R
Logged

Pages: [1]   Go Up
Jump to: