USART Overflow Interrupt

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

Hi,

 

I am trying to read data back data on my USART0 RX pin on my ATmega324P.  The data being return from the modem is +CMTI: "SM",1.  When this data is received I am trying to fire the RX interrupt but it will not fire.  So my question is, will the interrupt only fire with 8 bits, and anything larger it does not fire?  I have tried the overflow interrupt but that does not work either.

 

Thanks,

 

tuurbo46.

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

With the uart you need to ensure you have the baud rate set correctly. I'd suggest you post your code where you initialize the uart and interrupts along with your receive isr.

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

Nothing you have shown there is larger than 8 bits?!? If you are talking about the string:

 

"+CMTI: "SM",1"

 

then that is actually:

 

'+' - one 8 bit character

'C' - one 8 bit character

'M' - one 8 bit character

'T' - one 8 bit character

'I' - one 8 bit character

':' - one 8 bit character

(and so on)

 

As each of those characters comes in it will generate an RXC interrupt. In your interrupt handler you just read the character each time and add it into some buffer (usually a circular buffer, also called a ring buffer, also called a FIFO).

 

Elsewhere in your program you then have code that consumes the characters from the buffer. As long as you consume them at least as a fast as they are placed in the buffer (on average) then your only concern is to make the buffer large enough to cope with any "bursts" in the reception that you cannot immediately deal with. People often use a 16/32/64 byte buffer for this purpose.

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

Hi,

 

This is a cut down version of my code.  So my first step is to read the in coming message +CMTI: "SM",1 and send "A" to Terminal.  I have my Tx and Rx lines paralleled of to Terminal and I can see the +CMTI: "SM",1 coming on the Rx line, but the interrupt will not fire.  How would I create a circular buffer?

 

The Tx works fine, and I can print to Terminal and send SMS messages, its just receiving messages I am having a problem with.

 


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

#define BAUD 9600 
#define MYUBRR (F_CPU / (16UL * BAUD)) - 1 

volatile int8_t RxDataReady;

ISR(USART0_RX_vect) 
{	
	RxDataReady = 1;
}


int main (void)
{

		                                          
	UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0); 
	UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
	
	UBRR0H = ((MYUBRR) >> 8);
	UBRR0L = MYUBRR;

	 while(1)
	{

		if(RxDataReady) // Also tried 1<<RXC0
		{
			RxDataReady = 0;
						
			putcr_usart_0(0x41); // Print A to Terminal
			usart_flush_0();
		}
       
	

}

 

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

opps missed a bracket

 

}

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

If you are only setting a flag and then polling it in main() what is the point of using interrupts at all. Why not just have a while() loop in main() poll the RXC flag?

 

I thought you were talking about doing interrupts properly.

 

I'd also follow Kartman's advice in #2 for starters. Do you even know that the comms link is running at the right speed even before you try to use interrupts or anything like that? (IOW is the chip really running at 4MHz?)

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

Hi,

 

Kartman was correct about the baud rate on the modem.  I have changed this to suit my usart baud rate of 9600.  So now I have the opposite problem, the interrupt fires constantly and will not reset.  I have cut the Rx track and rerouted to confirm it is not a noise problem, and the problem is still current.  Also below is my clock rate setup to 4MHz:

 

// Clock Frequency 4MHz
CLKPR = (1 << CLKPCE); 
CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (1 << CLKPS0);

 

I have tried disabling the Rx interrupt, and using 1<<RXC0 in my if statement and the Rx buffer will not clear it keeps reloading and running and print A to terminal.

 

I have also tried adding Data = UDR0 in the if statement to clear the buffer but the will not clear, and A is repeatedly printed to terminal.

 

thanks,

 

Tuurbo46.
    

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

 

So now I have the opposite problem, the interrupt fires constantly and will not reset.

You >>must<< read UDR0.  That is the only way to clear RXCn.

 

ISR(USART0_RX_vect)
{
	RxDataReady = 1;
}

 

As soon as the ISR exits, it will run again, starving main code.  Put the read of UDR0 in the ISR:

ISR(USART0_RX_vect)
{
    RxDataReady = 1;
    UDR0;
}

 

However, I'm with Cliff:

If you are only setting a flag and then polling it in main() what is the point of using interrupts at all. Why not just have a while() loop in main() poll the RXC flag?

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Wed. Apr 6, 2016 - 07:28 PM