2

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.

Elliot Alderson
  • 31,192
  • 5
  • 29
  • 67
G-aura-V
  • 1,079
  • 1
  • 8
  • 21
  • 2
    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? – Justme Feb 20 '20 at 17:28
  • You might want to enable parity and check signal slew rate. – Tony Stewart EE75 Feb 20 '20 at 17:31
  • @Justme I have verified that my AVR clock is running at 1MHz. The supply voltage is 5V. I haven't checkd for framing errors. – G-aura-V Feb 20 '20 at 17:35
  • 1
    Yes, but what is the 1 MHz clock source and how precise it is? – Justme Feb 20 '20 at 17:36
  • I was told that the internal oscillator generates 8MHz. The prescaler of 8 gives me a clock frequency of 1 MHz. I – G-aura-V Feb 20 '20 at 17:40
  • No, it generates approximately 8 MHz. It is calibrated to within 2% at factory, in 25 °C and at 3V supply. It will have more tolerance when used at other supply voltages and other temperatures. In general the acceptable tolerance for UART comms is max 2%, so it may or may not work without user calibration. You can calibrate the RC oscillator with a for loop, printing calibration values to UART, and select the best calibration value from the middle that works. – Justme Feb 20 '20 at 17:56

1 Answers1

6

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.

Justme
  • 127,425
  • 3
  • 97
  • 261