Go Down

Topic: Interrupt for USART RX on Atmega328p seems not to fire (Read 1 time) previous topic - next topic

Feb 02, 2013, 11:13 pm Last Edit: Feb 02, 2013, 11:15 pm by Vaselinessa Reason: 1
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: [Select]
#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.

MarkT

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.
[ I won't respond to messages, use the forum please ]

#2
Feb 03, 2013, 01:13 am Last Edit: Feb 03, 2013, 01:26 am by Vaselinessa Reason: 1
Thanks. That's instructive.

PeterH


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.)
I only provide help via the forum - please do not contact me for private consultancy.

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

Thank you much.

Tyrostir

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: [Select]
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.

Robin2

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

Go Up