Cant get the USART_RX vector to fire

Go To Last Post
15 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey guys!
Its my first time on this forum, so I apologize in advance for any mistakes in my format.
Basically, I'm using an Arduino UNO with an Atmega328p, and I'm trying to make an LED (inbuilt led PINB5) glow when I give the character 'k' as an input in the Arduino IDE serial monitor. 
Please note that I am using Atmel Studio 7 to code and burn the Atmega328p, and the serial monitor from the Arduino IDE to enter data serially.

#define F_CPU 16000000UL 
#include <avr/io.h>     
#include <util/delay.h>  
#include <avr/interrupt.h>


void USART_Init()
{
    UBRR0H = (103>>8);
    UBRR0L = 103;
    UCSR0C = 0x00;
    UCSR0C |= 1<<USBS0;
    UCSR0C |= 3<<UCSZ00; // Purposely split up to make it clearer; Asynchronous, Parity Disabled, One Stop Bit, Eight Bit Transmission
    UCSR0B = (1<<RXCIE0)|(1<<RXEN0); // Enabling Receiver and receive complete interrupt enable
    
}

ISR(USART_RX_vect)
{
    char input = UDR0 ;
        PORTB= 0XFF; // Not a part of original code, just Testing if Interrupt is being called
    if (input == 'k')
    {
        PORTB |= 1<<5;    // Glow LED
    }
    else
    {
        PORTB &= ~(1<<5); // Low LED
    }
}


int main()
{
    USART_Init();
    DDRB |= 1<<5; // Pin B5 or 13 on the Arduino (inbuilt LED)
    sei();
    while (1)
    {	
    }
}

I do not get any output and the LED never glows.
I have observed that every time I hit enter in the serial monitor, the RX led on my Arduino glows, so data is definitely received. But the interrupt just wont fire!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If the data sent by the serial monitor is 3 bytes of "k", "CR" and "LF", the LED will turn on and off at your invisible speed.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

void USART_Init()
{
	UBRR0H = (103>>8);
	UBRR0L = 103;
	UCSR0C = 0x00;
	UCSR0C |= 1<<USBS0;
	UCSR0C |= 3<<UCSZ00; // Asynchronous, Parity Disabled, One Stop Bit, Eight Bit Transmission
	UCSR0B = (1<<RXCIE0)|(1<<RXEN0); // Enabling Receiver and receive complete interrupt enable
}

ISR(USART_RX_vect)
{
	char input = UDR0 ;
	PORTB = 0xFF;
}

int main()
{
	USART_Init();
	DDRB |= 1<<5; // Pin B5 or 13 on the Arduino (inbuilt LED)
	sei();
	_delay_ms(1000);
	while (1)
	{
	}
}

Thank you for your reply. I looked into what you said, and tried using the "Send" button on the Serial Monitor instead of using the Enter key. I also tried changing settings in the Arduino serial Monitor itself(image attached).
I still got the same results. I modified the code a little, to remove the if-else condition.(I have attached the modified code above).
Now the LED has to glow as soon as data has been received by the Arduino right?
Also, I just read that the RX led is driven by the usb-serial converter, so it tells me nothing about if my Arduino is receiving the data.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you're not getting any output it could be for several reasons:

  -  The application is not being loaded into the ATmega328P.

  -  The USART is not being initialized correctly.

  -  The application is not coded correctly.

  -  The application is not getting correct input.

 

  -  The application is not being loaded into the ATmega328P.  >>

    Does the code compile correctly?  How do you know?  AStudio puts out a lot of messages, perhaps one that indicates a compile/link error and is being scrolled out of view in the status window.

    Is the compiled hex file being loaded into the AVR?  Can you load the simple LED blink program from AStudio and see the UNO's LED go off and on?  What are you using to load this code: a USBasp on the ISP channel, or the bootloader installed in the Arduino's CPU?  Does this UNO have a separate AVR to drive the USB interface?  If yes, is the code in this secondary AVR working correctly?  Loading a hex file into a UNO/Nano with a USBasp will often destroy the link to the bootloader.  Could this have happened?

 

 

  -  The USART is not being initialized correctly.>> 

    A magic number is being used to set the Baud rate.   Why do you believe that this number is correct?

 

-  The application is not coded correctly. >>>

   Does this code work when you use the standard Arduino library for the USART:   Serial.h ,  and its tested, fully-debugged functions like:   Serial.available() and Serial.read()?

 

 

  -  The application is not getting correct input.>>

   Terminal programs can be tricky to use correctly, especially the Arduino Serial Monitor.   Is the COM port and baud rate setting correct?  Are you typing an key and expecting the ASCII value of that key to be sent immediately out of the PC to the AVR?   SerialMonitor has an input message box.  Characters being sent to the AVR need to entered here (the CHAR INPUT cursor needs to be in this box) and the SEND button clicked.  Then there are three options as to what chars are appended to the chars being transmitted: none, CR, CR/LF.    Is all this initialized correctly?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Welcome to AVRFreaks!
 

first the compiler knows how to write to 16 bit registers, you should not split then yourself.

ie. UBRR0 = value;

second, 8N1 is the default for UCSR0C so don’t mess with it.

the LED on the UNO is turned on when the port pin is low, not high, so try setting the port bit low and see if it comes on.

 

jim

 

 

(Possum Lodge oath) Quando omni flunkus, moritati.

"I thought growing old would take longer"

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you for your detailed answer.
- Does the code compile correctly? >>

Yes. "Building" the code in AStudio returns 0 Errors and 0 warnings as well. 

 

Can you load the simple LED blink program from AStudio and see the UNO's LED go off and on? >>

Yes. All programs work just fine. I have tried to perform the same task without using interrupts, and it works exactly as expected. The code is as follows: 

#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>  

void USART_Init()
{
	UBRR0H = (103>>8);
	UBRR0L = 103;
	UCSR0C = (0<<UMSEL00)|(0<<UPM00)|(0<<USBS0)|(3<<UCSZ00); // Asynchronous, Parity Disabled, One Stop Bit, Eight Bit Transmission
	UCSR0B = (1<<RXEN0)|(1<<TXEN0); // Enabling Receiver and Transmitter
}

uint8_t USART_Rx()
{
	uint8_t text;
	while (( UCSR0A & (1<<RXC0)) == 0) {}; // Do nothing until data have been received
	text = UDR0 ;
	return text;
}

int main()
{
	DDRB |= 1<<5; // Pin B5 or 13 on the Arduino (inbuilt LED)
	USART_Init();
	char input;
	while (1)
	{
		input = USART_Rx();
		if (input == 'k')
		{
			PORTB |= 1<<5;    // Glow LED
		}
		else
		{
			PORTB &= ~(1<<5); // Low LED
		}
		_delay_ms(1000);
	}
	return 0;
}

What are you using to load this code? >>

I'm using the bootloader in the Arduino's CPU like you said.

 

-  Does this UNO have a separate AVR to drive the USB interface?  >>
I'm not really sure about how this works unfortunately. I'm using the Arduino Uno Rev3 if that helps.

 

 Loading a hex file into a UNO/Nano with a USBasp will often destroy the link to the bootloader.  Could this have happened? >>

I have had success uploading many other programs, only having the issue while using this specific interrupt.

 

- A magic number is being used to set the Baud rate.   Why do you believe that this number is correct?>>
I have calculated this using the equation in the datasheet of the Atmega328p. I believe it is correct because i have had success using the aforementioned code, where i have used the same value.

 

Does this code work when you use the standard Arduino library for the USART:   Serial.h ,  and its tested, fully-debugged functions like:   Serial.available() and Serial.read()?

I haven't tried this out, will let you know as soon as I do.

 

Is the COM port and baud rate setting correct? >>
Since the code above works, they have to be, right?

 

- Is all this initialized correctly? >>
To the best of my knowledge, it seems to be so. Again, since the code above works just fine, it has to be. 
Also, in my second comment i modified the code to make the LED glow when any data is received. So it doesn't matter if the ASCII value of the key is sent right?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you! I think I'm starting to love it here already haha!
Anyway, I modified the code to account for what you said, and It still doesn't work unfortunately. 
I just realised that the LED is Active Low, but I got the desired output setting it to high (in the code without the interrupts). Maybe the other CR and LF bytes were in play here? 
Here is the modified code: 

#define F_CPU 16000000UL 
#include <avr/io.h>     
#include <util/delay.h>  
#include <avr/interrupt.h>
#define USART_BAUDRATE 9600 // Desired Baud Rate
#define BAUD_PRESCALER (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)

void USART_Init()
{
    UBRR0H = BAUD_PRESCALER >> 8;
    UBRR0L = BAUD_PRESCALER;
    UCSR0C = 0x00;
    UCSR0C |= 1<<USBS0; // Asynchronous, Parity Disabled, One Stop Bit, Eight Bit Transmission
    UCSR0B = (1<<RXCIE0)|(1<<RXEN0); // Enabling Receiver and receive complete interrupt enable
    
}

ISR(USART_RX_vect)
{
    char input = UDR0 ;
    PORTB = 0x00; 
}

int main()
{
    USART_Init();
    DDRB |= 1<<5; // Pin B5 or 13 on the Arduino (inbuilt LED)
    sei();
    _delay_ms(1000);
    while (1)
    {    
    }
}

Also, quick question. is it a good idea to use the delay function within the Interrupt?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 2

No, never put a delay in an ISR.
.
BTW the usual technique with UART development is to get micro to PC working first as this will prove the clocking. Only switch to micro Rx when Tx works.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I couldn't see any big problems with your code - so I compiled your exact #1 code & uploaded it to my UNO. I used miniterm from the python-serial module to connect (i'm on ubuntu at the moment so cannot use Br@y Terminal) I was not surprised to find your program works as you described.

 

Oh; I connected at 9600 baud - Did you ??

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

the LED on the UNO is turned on when the port pin is low, not high

What makes you think that?  The original Unos had the LED Anode connected to PB5 (w resistor.)

Around R3, they started using the space op-amp from their power circuitry as a driver, but it's still configured "non-inverting"

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The code from your initial post works fine on my Arduino, compiled and uploaded with:

 

avr-gcc -Os -mmcu=atmega328p foo.c

avr-objcopy -O ihex -R .eeprom a.out foo.hex

avrdude  -c arduino -p atmega328p -P /dev/tty.usbserial-A20e1Kh4 -Uflash:w:foo.hex

 

Could you have something weird in your AS project configuration?  Copy&paste the "output" from the compile into a message.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok so I'm not really sure where I went wrong, but after restarting my pc, copying my #1 code into a fresh AStudio 7 project, Compiling and Building the code (I usually just build it, not both), it works!
Could it be that something was wrong with my initial project?
@N.Winterbottom Yes, I did connect at 9600 baud.

@ westfw can you tell me how I can get that "output"? I get nothing of that sort when I build/compile the code.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@ westfw can you tell me how I can get that "output"? I get nothing of that sort when I build/compile the code.

 

If you pull down the "view" menu, there should be an option for "Output", which will show the (highly useful) log of the full build, rather than the (less useful) error/warning list that is shown by default.

I think.  Apparently there's a configuration that might (it's being discussed in another thread) make showing OUTPUT the default, and I think I have that set in my AS settings.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


_.zEuS wrote:
@ westfw can you tell me how I can get that "output"?

Illustrated instructions here: https://www.avrfreaks.net/commen...

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

westfw wrote:
What makes you think that? 

Must not have had my caffeine that morning, that's what I get for trying to remember stuff! smiley

Jim

 

 

(Possum Lodge oath) Quando omni flunkus, moritati.

"I thought growing old would take longer"