AVR UART problem

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

Hi all,

I am tearing my hair off while getting the UART of an ATMEGA8 chip to work. I have an Arduino Duemilanove baord, replaced the ATMEGA328 (has a boot loader) with a standard ATMEGA8-16U (no boot loader) from DigiKey. Since I have no virtual serial port driver for Solaris I have soldered a MAX233 to the TxD/RxD pins of the ATMEGA. I have written a small program for the ATMEGA chip that simply initializes the UART and continously sends out bytes to the serial port. I can see the bytes coming out of the serial port in front of and behind the MAX233 with the scope (well I can see that something is shifted out there, I can't see that's actually the bits that should be there but I guess that part is ok). The ATMEGA has a 16MHz quarz. I have set the fuse bytes with

avrdude -c avrispmkII -P usb -p atmega8 -U lfuse:w:0xef:m -U hfuse:w:0xc9:m

and verified with

#define F_CPU 16000000UL /* 16 MHz CPU clock */

while (1) /* loop forever */
{
PORTB |= _BV(PB5);
delay_ms(100);
PORTB &= ~_BV(PB5);
delay_ms(900);
}

that the clock frequency is correct. The LED actually blinks once a second as it should so I understand the chip really uses the 16MHz.

I am now using

void USARTInit(uint16_t value)
{
// Set Baud rate
UBRRH = 0;
UBRRL = 103; // 51 = 19200 baud; 103 = 9600 baud

// 8N1
UCSRC = (1<<UCSZ1) | (UCSZ0);

// Enable receiver and transmitter
UCSRB = (1<<RXEN) | (1<<TXEN);
}

to initialze the UART and am sending bytes with

void TxByte (uint8_t data)
{
// Wait for empty transmit buffer
while ( !( UCSRA & (1<<UDRE)) );
// Putting data into the buffer, forces transmission
UDR = data;
}

int main (void)
{
DDRB = 0xff;
USARTInit(103);

while (1) /* loop forever */
{

TxByte(65);
TxByte(66);
TxByte(67);
TxByte(13);
TxByte(10);
}
}

I have connected the serial port of a Solaris machine to the MAX233, initialized it to 9600 baud and am reading data. I only receive 00 bytes and am out of ideas! :-(

Hints are greatly appreciated! Thanks!

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

Quote:

continously sends out bytes

Quote:

I can see the bytes coming out of the serial port in front of and behind the MAX233 with the scope (well I can see that something is shifted out there, I can't see that's actually the bits that should be there but I guess that part is ok).

Send continual 'U' characters in a loop at 8,n,1. Then you get a square wave output and can check your bit width(s) on a 'scope.

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

9600 bps is 104 usec per bit

Imagecraft compiler user

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

If you have a scope it's really easy to see what's coming out of a UART. Put a delay between each character so you can identify the start bit. Send a character that has a 1 in the LSB (so you can see the end of the start bit, and determine the bit width and thus the baud rate). Just loop sending that character with a delay.

Remember that RS-232 polarities are opposite the polarities coming out of the AVR. That is, the idle ('1') state is -V, and '0' state is +V.

My first guess, if you're getting 00 bytes, is that you are sending data at a much slower baud rate than you are receiving, so that 00 data is just the very stretched out start bit.

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

Quote:

// 8N1
UCSRC = (1<<UCSZ1) | (UCSZ0);


Better check that one again. ;)

[edit] I was just referring to the lack of the shift to change bit position to bit mask, but as this is a Mega8 then there is a UCSEL or similar needed as well to work with register C.

Lee

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.

Last Edited: Mon. Feb 8, 2010 - 07:22 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Better check that one again. :wink:

Word.

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

theusch wrote:
Quote:

// 8N1
UCSRC = (1<<UCSZ1) | (UCSZ0);


Better check that one again. ;)

[edit] I was just referring to the lack of the shift to change bit position to bit mask, but as this is a Mega8 then there is a UCSEL or similar needed as well to work with register C.

Lee

Uaghh!

UCSRC= (1<<URSEL) | (3<<UCSZ0);

and it works! :D I checked the signal (sending Us) with the scope, one bit was 1.4ms wide. No wonder the other side received only 00s.

This forum rocks!! Thanks a lot for your help with this!

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

Quote:
UCSRC= (1<<URSEL) | (3<<UCSZ0);

and it works!

Now comment that line out altogether and it will STILL work as the USART deafult to those settings at power up. ie waste of efforts. :)

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly