0

Below is a simple USART code for ARDUINO written in Pure C. But due to uknown(in reference to me) reasons, the code is not provicing desired output.

Can someone point out the error in the code. I cannot use the Arduino built in function Serial.begin as i need to use USART receive interrupts.

#include <avr/io.h>
#define F_CPU 16000000
#define BAUD 9600 
#include<util/setbaud.h>

void UART_Init();

void setup() 
{
    UART_Init();
}

void loop()
{
    UART_Transmit('c');
}

void UART_Init()
{
   UBRR0H = UBRRH_VALUE;
   UBRR0L = UBRRL_VALUE; 
   UCSR0B = (1<<RXEN0) | (1<<TXEN0);
   UCSR0C = (3<<UCSZ00);
}

void UART_Transmit(unsigned char data)
{
    while(!(UCSR0A & (1<<UDRE0)));
    UDR0 = data;
}
  • Compiled as an Arduino sketch, your code runs like a charm on my Uno. How did you compile it? – Edgar Bonet Jul 4 '17 at 7:24
  • @EdgarBonet I did compiled it on Arduino IDE . There was no error in the code. But after uploading to the board the output received is not as expected. – Sreez.. Jul 4 '17 at 7:29
  • What kind of output did you expect? I see a long stream of "ccccccccccccccccccccccc...", and that's what I expect from reading the code. – Edgar Bonet Jul 4 '17 at 7:33
  • @EdgarBonet I too expect that only. But am not getting it.In my serial monitor, I get only square boxes – Sreez.. Jul 4 '17 at 7:34
  • 1
    At 115200 baud rate, the correct output is received. But for 9600, the output is square boxes. – Sreez.. Jul 4 '17 at 7:42
0

Finally I figured it out.

The UBRR0 calculation was the mistake

For making the code work for baud rate 9600, we need to set the equation as:

UBRR0 = (F_CPU / 4 / baud - 1) / 2;

and also double the USART speed by setting :

UCSR0A = (1<< U2X0)

I hope someone will find this information helpful.

  • util/setbaud.h defines USE_2X to 0 or 1 depending on whether the U2X bit is needed. Then you can UCSRA |= (USE_2X << U2X);. – Edgar Bonet Jul 4 '17 at 9:31
  • @EdgarBonet Thanks for the help man. It works like a charm. – Sreez.. Jul 4 '17 at 11:27
0

UBRR0 = (F_CPU / 4 / baud - 1) / 2;

you probably want to check the datasheet for that.

One way to code it is to change it based on the U2X bit, like this:

UxBRR=F_UART / ((UxCSRA & (1<<U2X0))?8:16) / baud - 1;          //generate baud rate register

So the user can change the U2X bit freely and the software will take care of it.

there is one set of uart polling and interrupt-driven routines that I use: https://github.com/dannyf00/My-MCU-Library/tree/master/UART/UARTISR/ATMega328p

they have the same user interface so can be exchanged freely.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.