4
\$\begingroup\$

I have been trying to get the USART RX interrupt trigger working on my ATmega168A using the tutorial here (updating my registers as per the datasheet): Tutorials

I have setup the system to use a baud of 4800 at a freq of 1MHz (8Mhz internal oscillator div/8), prescale value of 12 came from the microchip datasheet.

Using the normal serial communications (inside my main loop), the system works as expected and echos the transmitted char back to the pc console. I then added the 2 lines at the end of the function USART_Init() which should enable the RX interrupt and the global interrpt but when typing over the same serial connection which worked, noting happens which suggests to me that either its not triggering or theres an error.

I have searched google and the stack overflow for other instances and I havent been able to find anything which matches my issue or the many links i have found suggest doing things which I already have in my code/tried before.

Have I missed something or have I got a fault in something?

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

#define F_CPU 1000000UL
#define BAUD 4800
#define BAUD_PRESCALE 12


void USART_Transmit( unsigned char data )
{
/* Wait for empty transmit buffer */
while ( !( UCSR0A & (1<<UDRE0)) )
;
/* Put data into buffer, sends the data */
UDR0 = data;
}

unsigned char USART_Receive( void )
{
/* Wait for data to be received */
while ( !(UCSR0A & (1<<RXC0)) )
;
/* Get and return received data from buffer */
return UDR0;
}

void USART_Init( unsigned int ubrr)
{
/*Set baud rate */
UBRR0H = (unsigned char)(ubrr>>8);
UBRR0L = (unsigned char)ubrr;
/* Enable receiver and transmitter */
UCSR0B = (1<<RXEN0)|(1<<TXEN0);
/* Set frame format: 8data, 1stop bit */
UCSR0C = (0<<USBS0)|(1<<UCSZ00)|(1<<UCSZ01);
/*enable RX interrupt */
UCSR0B |= (1 << RXCIE0);
sei();
}

int main(void)
{
USART_Init(BAUD_PRESCALE);
while (1) 
{
    //a = USART_Receive();
    //USART_Transmit(a);
    _delay_ms(100);
}
}

ISR(USART_RX_vect, ISR_BLOCK){
char ReceivedByte ;
ReceivedByte = UDR0 ; // Fetch the received byte value into the variable " ByteReceived "
UDR0 = ReceivedByte ; // Echo back the received byte back to the computer

}

I am using ATmel Studio 7 with WinAvr to code, compile and program the chip.

\$\endgroup\$
2
  • \$\begingroup\$ I believe with that particular AVR you need to use 'USART0_RX_vect' instead of 'USART_RX_vect' \$\endgroup\$ Mar 22, 2019 at 22:16
  • \$\begingroup\$ Can you try toggling an IO line inside the ISR just to see if it is being called? Maybe check RXCIE0 in the header is really 7 (or just put 7 in the code to see)? \$\endgroup\$
    – bigjosh
    Aug 22, 2021 at 7:04

2 Answers 2

0
\$\begingroup\$

You need to change ISR(USART_RX_vect, ISR_BLOCK) to ISR(USART0_RX_vect, ISR_BLOCK)

Beware when following code examples online. With the newer chips they started adding numbers to a lot of the registers/macros.

\$\endgroup\$
11
  • \$\begingroup\$ according to the datasheet the source is USART, RX. When I change the vector to "ISR(USART0_RX_vect, ISR_BLOCK){" it is no longer highlighted and I get the following warning: 'USART0_RX_vect' appears to be a misspelled signal handler. I compiled the code anyway and tried it and still nothing appears to work, I am comparing all tutorials with the datersheet to make sure i get the values correct \$\endgroup\$
    – NoLiver92
    Mar 22, 2019 at 22:23
  • \$\begingroup\$ That is...weird. I have Studio 7 open right now and I am not having that issue. Do you have the correct chip selected in your project? \$\endgroup\$ Mar 22, 2019 at 22:25
  • \$\begingroup\$ Yes, I have the ATmega168A under project properties -> Device. \$\endgroup\$
    – NoLiver92
    Mar 22, 2019 at 22:27
  • \$\begingroup\$ Ok, just checking my project, I'm using an Atmega328P (same family, same datasheet) and in the chip header (iom328pb.h) I can see that USART0_RX_vect is mapped to _VECTOR(18) and there is no USART_RX_vect \$\endgroup\$ Mar 22, 2019 at 22:28
  • \$\begingroup\$ Alright, I have verified what you are saying...oddly those chips do in fact use different macros for that interrupt. Sorry, I am out of ideas. \$\endgroup\$ Mar 22, 2019 at 22:33
0
\$\begingroup\$

There is nothing wrong with the ISR code. I just tested this on an Arduino UNO (basically an ATMEGA168 running at 16Mhz with a USB adapter connected to the AVR USART, ultimately compiles with avr-gcc) and it successfully echoed chars back at me with the only the ISR code uncommented.

I did have to manually change the BBR value to fit the clock rate.

Here is the exact code I used... https://gist.github.com/bigjosh/e0a386d10d8dff3a584e9489ac97ddb3

Just to be 1000% sure the ISR was executing, I even changed it to this...

ISR(USART_RX_vect, ISR_BLOCK){
   char ReceivedByte ;
   ReceivedByte = UDR0 +1 ; 
   UDR0 = ReceivedByte ; 
}

...and it incremented the echoed char by 1.

So it appears the problem is not in the code. Maybe in the environment, or test set up, or something else?

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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