AT MEGA168 USART TROUBLE

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

Hi everyone, I am trying to communicate serially with my PC via the AVR mega168 but for some reason the controller doesn't sync immediately with the Hyper terminal and sometimes I receive garbage characters. Please can anyone check my code and post some advice, thank you.
(crystal 18.432MHz, Baud 2400)

#include

void USART_Init(void)
{
UBRR0L=0xDF;
UBRR0H=0x01;
UCSR0C = (0<<UMSEL01)|(0<<UMSEL00)|(0<<UPM01)|(0<<UPM00)| (0<<USBS0)|(1<<UCSZ01)|(1<<UCSZ00)|(0<<UCPOL0);
UCSR0B = (1<<TXEN0);
}

void USART_vSendByte(uint8_t u8Data)
{
while((UCSR0A&(1<<UDRE0)) == 0);
UDR0 = u8Data;
}

int main(void)
{
USART_Init();

while(1)
{
USART_vSendByte('g');
}

return 0;
}

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

Wrong forum. Please read forum guidelines.

[so moved from Tutorial to AVR]

Regards,
Steve A.

The Board helps those that help themselves.

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

With continuous sending and no idle time, it may take a while to re-sync once the first framing error is logged with n,8,1. Put some milliseconds delay at startup--the transceiver may well not yet be "warmed up". Two stop bits may also help.

[I've made posts before about "You kids always have to go so fast". In this case with the test program, it brought a smile with an 18MHz AVR doing 2400bps. :) ]

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Thanks for you reply. I tried to put a delay after USART_Init(); but still the same result. Actually I got this code which was for a mega8 (8MHz,2400 baud):

#include
void USART_Init(void)
{

UBRRL=207;
UBRRH=0;
UCSRB=(1<<TXEN);
UCSRC=(1<<URSEL)|(0<<UMSEL)|(0<<UPM1)|(0<<UPM0)|(0<<USBS)|(0<<UCSZ2)|(1<<UCSZ1)|(1<<UCSZ0);

}

void USART_vSendByte(uint8_t u8Data)
{
while((UCSRA&(1<<UDRE)) == 0);
UDR = u8Data;
}

int main(void)
{
USART_Init();

while(1)
{
USART_vSendByte('g');
}

return 0;
}

I tried this code on a simulator and it worked perfectly with a mega8. Then I arranged the registers for the mega168 and it didn't work (the above program). That is why I can't figure out where the problem is.
If some one please can post a sample code which works perfectly, it would be great.

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

Would you kindly stop duplicating your posts?

Warning: Grumpy Old Chuff. Reading this post may severely damage your mental health.

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

is 18MHz a valid clock freq for the mega168?

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

I posted here because first I posted in the wrong section. Any way, thanks for your relys so far. Yes 18MHz is valid and I am using it because the datasheet says that with 18MHz there wouldn't be error in the baud. Do you see something wrong in the code please?

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

is it advisable to have a pull-up resistor on Tx pin? RS232 output is normally high. Does it have trouble syncing when you reset you device only?

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

Syncing is a problem all the time because the uC doesn't sync immediatly so I restart the uC several times. What I can't understand is that this code works perfect on a mega8 but then it doesn't on the mega 168! And I am trying with a simulator and with a real uC and I am having the same result, garbage data.

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

are all the garbage characters the same? Like 'g' but with the 8th bit set? Or do the gabage characters seem random?

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

when I try it on the simulator, I see the same character on the terminal(not 'g'), and in real(Hyper terminal) most of the time nothing and some times different characters, but very few.

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

207 is the right number for the UBBRL at 16 MHz, not 18.4320 MHz. Also it's for 4800 baud not 2400.

For 18.4320MHz you need 479 in UBRRH:UBBRL.

You can't more than double the clock rate and expect the Baud rate to stay the same; check your datasheet!

Cheers,

Joey

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

479 is decimal. In hex his 01DF is correct in his original post.

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

I am trying different bauds with different crystals just to be sure. Is the initialization code correct please?

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

Is the RS232 cable loose? I have seen sync issues when the connection is intermittent.

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

Has any body worked with the Mega 168 usart please? beacuse I am having my douts how it really works. I am starting to belive tha this uC doesnt support the USART. If any one did, please post the code, and if there are any tricks please send them too. thank you

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

Yes - it works perfectly for me. I can't give you any C code as I only work in ASM.

If you set up the various registers correctly, and take into account your CPU frequency correctly, it will work.

Are you using a max232 inverter/level translator? If not, you will have no chance of seeing anything on the PC - so what is your circuit diagram??

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

Quote:

take into account your CPU frequency correctly

That is normally the main problem with AVR USARTs. Are you SURE your AVR is running at the speed you think it is? How have you verified that?

[We ship 10k+ of that AVR family with USART each year, including '168.]

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

I use 168's all the time and the first thing I start with is the UART to give a debug channel so there is no question whatsoever that it works.

#include 
#include 

int uart_putc(char c, FILE *unused) {
#ifdef __AVR_ATmega168__
	while (!(UCSR0A & (1<<UDRE0)));
	UDR0 = c;
#else
	while (!(UCSRA & (1<<UDRE)));
	UDR = c;
#endif
	return 0;
}

FILE uart_str = FDEV_SETUP_STREAM(uart_putc, NULL, _FDEV_SETUP_WRITE);

int main(void) {

#ifdef __AVR_ATmega168__
	UBRR0L = 51; // 9600 @ 8MHz
	UCSR0B = (1<<TXEN0); // only using it as output debug channel
#else
	UBRRL = 51; // 9600 @ 8MHz
	UCSRB = (1<<TXEN); // only using it as output debug channel
#endif

	stdout = &uart_str; // printf to UART

	printf("Hello world\n"); // UART
}

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

Hi, yes I am using the max232 to invert the voltages. I connected the TX pin of the uC to pin 11(max232) and pin 2 of the female serial to pin 14(max232). I am using a 4MHz crystal on my avr board and for the baud calcualtions, I am taking them from the data sheet.

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

Quote:

I am using a 4MHz crystal on my avr board

And you've enabled its use?

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

You mean the fuse settings? This is how I am setting the fuse bits:
EXT:F9
HIGH:DC
LOW:F7