2
\$\begingroup\$

I am trying to implement following program in Atmega328P.

#define F_CPU 1000000UL
#include <avr/io.h>
#include <uart.h>
#include <util/delay.h>
#define BUAD 9600
#define BSR ((F_CPU/16/BUAD)-1)

void initUart()
{
    UBRR0H = (BSR>>8);
    UBRR0L = BSR;                                    /////// setting the baud rate
    UCSR0B = (1<<TXEN0) | (1<<RXEN0);               //////// Enabling the transmitter and receiver
    UCSR0C = (1<<UCSZ00) | (1<<UCSZ01);         //////// Setting the frame of 8 bit for character and 1 stop bit.   
}


void sendByte(uint8_t data)
{
    do 
    {
    } while (!(UCSR0A & (1<<UDRE0)));
    UDR0 = data;
}


uint8_t receiveByte()
{
    do 
    {} while (!(UCSR0A & (1<<RXC0)));
    return UDR0;
}


int main(void)
{
    char share;
    DDRB = 0xff;
    initUart();  
    while (1) 
    {
        share = receiveByte();
        sendByte(share);
        PORTB = share;

    }
    return (0);
}

What this program basically does is take a character from the terminal (I tried Bray's terminal and Tera term), display it within the terminal and show the corresponding ASCII value of the character in 8 LEDs connected to PORT B.

I can't state my problem in words so please bear with me. The problem is as follows:

When I send 'a' , I expect the LED to light up as (0b01100001). But my LEDs show up 0b11100001. The last bit is the first bit to be off in the upper nibble but that's not what I am getting.

I send 'a' but I receive á (0b11100001). Similarly when I send 0 (0b00110000), I receive 'p' (0b01110000). The first bit to be reset in the uppper nibble always sets whenever I send something. Then the wrong character is displayed in the terminal and the wrong LED representation.

I feel like there is something wrong when I receive my character into the chip from the terminal but can't figure out what exactly.

\$\endgroup\$
  • 2
    \$\begingroup\$ Is both the PC and AVR using same baud rate and communication parameters? Have you verified the AVR clock really is running at 1 MHz? Did you check for framing errors? Are you running with 1 MHz internal oscillator? Is it calibrated to have less than 2% error? What is the supply voltage? \$\endgroup\$ – Justme Feb 20 at 17:28
  • \$\begingroup\$ You might want to enable parity and check signal slew rate. \$\endgroup\$ – Tony Stewart Sunnyskyguy EE75 Feb 20 at 17:31
  • \$\begingroup\$ @Justme I have verified that my AVR clock is running at 1MHz. The supply voltage is 5V. I haven't checkd for framing errors. \$\endgroup\$ – Giga-Byte Feb 20 at 17:35
  • 1
    \$\begingroup\$ Yes, but what is the 1 MHz clock source and how precise it is? \$\endgroup\$ – Justme Feb 20 at 17:36
  • \$\begingroup\$ I was told that the internal oscillator generates 8MHz. The prescaler of 8 gives me a clock frequency of 1 MHz. I \$\endgroup\$ – Giga-Byte Feb 20 at 17:40
6
\$\begingroup\$

1 MHz clock cannot achieve 9600 BPS rate with 16x oversampling. You must use faster clock, slower baud rate, or use U2X bit to enable 8x oversampling.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ That's it! I just halved the baud rate and the problem is solved. Thank you @Justme. \$\endgroup\$ – Giga-Byte Feb 20 at 17:54

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.