# USART not working :( Tried multiple examples from the internet

Status
Not open for further replies.

#### Marks256

##### New Member
The target is an atmega16 running at 7.3728MHz.

I've been trying all day just to get an EXAMPLE (as in copy/paste from the internet) for the USART on my avr to simply echo a bit from a PC running a terminal program.

I've tried at minimum 15 different examples, including interrupt driven ones, and non interrupt driven ones. and not a single one of the examples have worked for me. I have however, had the most luck with the following code;

Code:
#include <avr/io.h>
#include <util/delay.h>

#define USART_BAUDRATE 9600
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)

int main (void)
{

UCSRB |= (1 << RXEN) | (1 << TXEN);   // Turn on the transmission and reception circuitry
UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1); // Use 8-bit character sizes

UBRRL = BAUD_PRESCALE; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register
UBRRH = (BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register

for (;;) // Loop forever
{
while ((UCSRA & (1 << RXC)) == 0) {}; // Do nothing until data have been recieved and is ready to be read from UDR

ReceivedByte = UDR; // Fetch the recieved byte value into the variable "ByteReceived"

while ((UCSRA & (1 << UDRE)) == 0) {}; // Do nothing until UDR is ready for more data to be written to it
UDR = ReceivedByte; // Echo back the received byte back to the computer
}
}
however when ever i press a key on the terminal, all i get back is a "+", no matter what the key i pressed was! Further investigation shows that UDR always equals 0xFF! but this example at least RESPONDS to a keypress for me. Any other ones don't even respond to a key press. All of the examples have compiled without a single error or warning.

Any ideas?

#### fermat7

##### Member
try to use brackets to specify WHILE instructions....

#### Marks256

##### New Member
there are brackets after the while statement;

while ((UCSRA & (1 << RXC)) == 0) {}; // Do nothing until data have been recieved and is ready to be read from UDR

#### Papabravo

##### Well-Known Member
You might want to eliminate the use of the |= operator on the control registers. Usually with control registers you want to set each bit to a particular value regardless of the previous contents.

Next suggestion is debug your transmitter before you worry about your receiver. Transmit the same character repeatedly so you can observe the TxD line with a scope or a terminal program. I like the upper case 'U' which is 0x55 in hex. On the scope you see a low going start bit followed by alternating 1's and zeros for the next eight bits followed by the high stop bit. Makes it real easy to see if you got the bit timing correct.

Receiving characters and echoing is actually step 2.

Don't forget to verify that your terminal program is setup correctly and that the cable is the way you expect it to be -- either straight through or null modem.

With your cable plugged into the computer make sure the pin you think is TxD from the computer is at a valid RS-232 level. This would probably be any voltage between -25V and -3V which is the value of a 'mark' or idle condition. Also make sure that the Rxd input is near ground when it is open (not connected to anything. Lastly make sure that the computer's TxD is connected to your ATmega16's RxD and that the computer's RxD is connected to the Atmega16's TxD

The UARTS on these chips work nearly flawlessly after you get over the initial hump.

Good luck,
PB

PS Reread the datasheet one more time time just for good luck. It's here:

http://www.electro-tech-online.com/custompdfs/2009/06/8154S.pdf

Last edited:

#### Papabravo

##### Well-Known Member
there are brackets after the while statement;

while ((UCSRA & (1 << RXC)) == 0) {}; // Do nothing until data have been recieved and is ready to be read from UDR
You actually have an empty block followed by a null statement. You don't actually need both of them. Either the null statement ( the ; ) or the empty block will suffice. Look at the compiled code if in doubt.

#### Marks256

##### New Member
Think i may have found the problem...

It is true i had a 7.3728MHz clock, but the fuse for the 1MHz internal clock was set. So it was running at 1MHz.

I need to do a bit of re-arranging on my work bench, and i'll give it a try making sure i'm using the external clock

#### Marks256

##### New Member
Yep that worked. I just had to specify i was using an external clock....

Thanks for the support!

Status
Not open for further replies.