2

I was able to use USART without interrupt driven and it worked perfectly! However, when I tried adding interrupt on USART_RX_vect, the program does not work as expected anymore.

Below is my small program. The expected behavior of this program is everytime I press a button the LED should toggle its state, but also by default the LED will toggle its state every 500ms. Right now, the LED toggles every 500ms but the moment I press a button on my machine keyboard to send data to the ATmega328p, the program stops (the led freezes on its last state).

I am not using an external clock, but I wonder if that could be the problem or I am missing something in my code that I can't figure out.

I appreciate any help. Thank you.

#ifndef F_CPU
#define F_CPU 1000000UL
#endif

#define FOSC F_CPU
#define BAUD 4800
#define MYUBRR FOSC/16/BAUD-1

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

void USART_Init(unsigned int ubrr) {
   UBRR0H = (unsigned char)(ubrr>>8);
   UBRR0L = (unsigned char)ubrr;
   UCSR0B = (1<<RXEN0) | (1<<RXCIE0);
   UCSR0C |= (1<<UCSZ00 | (1 << UCSZ01));
}

IRS(USART_RX_vect) {
    PORTC ^= (1 << PC5);
}

int main(void) {
    USART_Init(MYUBRR);
    DDRC |= (1 << PC5);
    sei();
    while(1) {
        PORTC ^= (1 << PC5);
        _delay_ms(500);
    }
    return 0;
}

Edit#1: I modified IRS handler:
Code:

IRS(USART_RX_vect) {
    while(!(UCSR0A&(1<<RXC0))){};
    unsigned char received = UDR0;
    PORTC ^= (1 << PC5);
}

Status: Program does not work.

Edit#2: Fixed typo ISR instead of IRS (pffff)

Solution: I was missing the code for consuming the RX buffer and I had a typo: IRS should be ISR. Thanks for @Edgar Bonet and @Majenko for the help!

3

Just replace IRS (Internal Revenue Service) with ISR (Interrupt Service Routine).

  • Nice catch, I didn'even think about this ... I thought the compiler would help me fix my syntax :/ – COMP Aug 2 '17 at 20:09
  • @COMP: It did help me: warning: type of ‘__vector_18’ defaults to ‘int’ and warning: unused parameter ‘__vector_18’. – Edgar Bonet Aug 2 '17 at 20:16
  • @COMP: And warning: return type defaults to ‘int’ for the IRS() function. – Edgar Bonet Aug 2 '17 at 20:17
  • 1
    Good catch there ;) I suspect it may actually be a combined problem including not reading the RX buffer, and both needed to be fixed to see it work. – Majenko Aug 2 '17 at 20:21
  • EdgarBonet you're right, I ignored my console as long as it passed the syntax analysis phase. @Majenko yes it's both answers combined that fixed my problem. Thanks! – COMP Aug 2 '17 at 20:25
3

I suspect if you were a fly you would see your LED flashing very very rapidly.

The reason is, your interrupt will constantly trigger itself over and over and over again.

Why? Because you aren't reading the incoming character from the RX buffer. And until you do the chip will keep alerting you that there is something there to read by triggering the interrupt.

  • I tried modifying my code, not sure if that is enough to consume the character from the buffer. (Refer to Edit#1) – COMP Aug 2 '17 at 19:53
  • It should be - if the compiler doesn't optimize it out (which it shouldn't since one half is volatile). However, I usually simplify it to: (void)URD0; – Majenko Aug 2 '17 at 19:54
  • Unfortunately it did not fix my program, but it's for sure something I didn't know. Thanks! – COMP Aug 2 '17 at 19:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.