NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Microcontroller Programming » UART interrupt issues

May 19, 2011
by gcharris
gcharris's Avatar

This is my first foray into interrupts. Basically I'm looking to send a character from my computer to the microcontroller via serial, have it trigger an interrupt and modify a global variable that will be used as control other aspects of my project. I asn't able to get it to work, so I tried to just do a simple loopback of text typed in.

I stripped down the file to the absolute bare minimum and I still cannot get any return output to my terminal.

Any thoughts as to where I'm going wrong?

Thanks

Grant

#define F_CPU 14745600

#include <stdio.h>
#include <math.h>

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <inttypes.h>

#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"
#include "../libnerdkits/uart.h"

int main() {

  // start up the serial port
  uart_init();
  sei();

  return 0;
}

 ISR(USART_RX_vect)
{
   char ReceivedByte; 
   ReceivedByte = UDR0;
   UDR0 = ReceivedByte;

}
May 19, 2011
by Noter
Noter's Avatar

You have to check the status register to see if a byte has been received before getting it from UDR0. Likewise, you have check it again to see if it is idle before writing to UDR0.

  while(!(UCSR0A & (1<<RXC0)));
  ReceivedByte = UDR0;
  while (!(UCSR0A & (1<<UDRE0)));
  UDR0 = ReceivedByte;
May 19, 2011
by Noter
Noter's Avatar

Oops, since you are in an interrupt you don't need to check to see if the character is ready to read. You still need to check before writing and may need to move your write logic back to the main loop. I don't know if you can write before leaving the interrupt routine.

May 19, 2011
by Noter
Noter's Avatar

Actually, I am wrong on both counts. Before using the interrupt, the receive interrupt must be enabled. My chip runs at 18432000hz so I also have to reset the baud rate after calling uart_init(). The final problem is that you must not return from you main() so I added the while loop.

#define F_CPU 14745600
//#define F_CPU 18432000

#include <stdio.h>
#include <math.h>

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <inttypes.h>

#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"
#include "../libnerdkits/uart.h"

int main() {

    // start up the serial port 
    uart_init();
    // set baud for 115200
    UCSR0A = 0;
    UBRR0L = (F_CPU/(16 * 115200L ))-1;
    // turn on receive interrupts
    UCSR0B |= _BV(RXCIE0);

    // enable global interrupts
    sei();

    while(1);
}

 ISR(USART_RX_vect)
{
    char ReceivedByte; 
    ReceivedByte = UDR0;
    UDR0 = ReceivedByte; 
}
May 19, 2011
by gcharris
gcharris's Avatar

Awesome, thanks.

I'll try it out later tonight once I get home.

May 20, 2011
by gcharris
gcharris's Avatar

Worked wonderfully, thanks

Post a Reply

Please log in to post a reply.

Did you know that you can input numbers in binary via a DIP switch, and output them to the LCD? Learn more...