I was able to run and get output using the code provided along with the book. I use Proteus to simulate the output since I don't have controller in hand.
Today I tried to write a simple uart program by referring data sheet.
/*
* uart.c
*
* Created: 05-09-2018 09:55:36 PM
* Author : New User
*/
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
UCSR0B = (1 << RXEN0) | (1 << TXEN0);
UCSR0C = (1 << UCSZ01) | (1 << UCSZ02);
UBRR0L = 6;
char data;
while (1)
{
while (!(UCSR0A & (1<<RXC0)));
data = UDR0;
while (!(UCSR0A & (1<<UDRE0)));
UDR0 = data;
}
}
When I simulate code in Proteus I get weird characters in virtual terminal.
First thought it might be due to error in baud rate.
As my understanding default F_CPU of Atmega168 is 1MHz if I don't use any external crystal oscillator. So for a baudrate 9600 U0BRR = 6 from this equation
U0BRR = (F_CPU/(16 * 9600)) - 1 = (1000000/16*9600)-1 = 5.51 ~6
Also in the datasheet, U0BRR is 6 for a baud rate 9600 for 1MHz clock
So what's happening here??
IDE: AtmelStudio 7
I've attached my my Proteus settings
Is there anything i should change in Proteus??
I have an arduino(ATMEGA328), and after some search I found out same code works on both controllers. Changed UBRR0L to 103 for 16MHz. Also tried with changing F_CPU to 16000000UL. Not working there too.
@AthulSNair, I think you're on the right path, it will have some pain. Don't fear taking parts from the Arduino core, but the uart is probably not a good one to look at. There are many AVR examples to look at and a few work well, I weaved a few parts from various places into this:
Probably the coolest part was figuring out streams so it could be passed into the stdout and stdin and then used with avr-libc stdio library sort of like found in Unix/Linux (e.g. libc and the updated version newlib).
The end result is printf("hello world\n") works as expected. Also getchar(), which takes a single byte from the stream buffer.
The Standard IO facilities is a gold mine after you get it to work.
I experimented (on an actual Uno, with 16MHz clock, and UBRR0L = 103), and I had a lot of trouble getting it to work, too.
The code mostly looks pretty correct (see below.)
I discovered a couple of interesting things:
While it looks like a bitrate problem, SOME of the characters echoed correctly. If I sent "abcd", I got back "ybc" ... that's weird.
is incorrect. UCSZ02 is actually off in UCSR0B. Here, there should be USCZ00 (UCSZ02 should default to 0, which is the value you want, so you don't actually need to set it.
I COULD get it to work by adding:
UCSR0A = 0;
To the initialization code. I don't have any current theory as to why this helps, except a vague though that perhaps the received data is "out-of-sync" with the transmitted data (send 'a', get some trash that was already in the buffer. Except this doesn't hold up very well.)
That reminds me of the startup glitch someone alerted me to and I verified some time back.
Optiboot seems to deal with it, no clue how, but when I turn on the UART (without optiboot) it glitches the TX line. The board I have linked to has a transceiver that I disable before turning on the UART so the glitch does not get into the communication channel.