Search code examples
embeddedavratmegaavr-gccatmega16

Why setting uart to double speed mode when gives the right output and normal mode with same baud rate doesn't in atmega32?


To get right output I had to set U2X bit to one and when I set it to zero and change value of UBRR Register the output makes no sense. I checked that I'm using right values from datasheet table but it doesn't give right output at U2X=0.

my .h file

#ifndef USRAT_TEST_H_
#define USRAT_TEST_H_

#include <avr/io.h>
void USRAT_INIT(uint16_t bd);
char USRAT_RECIEVE_CHR(void);
void USRAT_SEND_CHR(char c);
#endif /* USRAT_TEST_H_*/

my .c file

#include <avr/io.h>
#define F_CPU 2000000UL
#include <util/delay.h>
#include "USRAT_TEST.h"
void USRAT_INIT(uint16_t bd)
{
    UCSRA = (1<<U2X);//when removing this line and edit F_CPU/8 to F_CPU/16 things go wrong
    UCSRB|=(1<<RXEN)|(1<<TXEN);// enable send and receive
    UCSRC|=(1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);//8-bit width 
    UBRRL=(F_CPU/8/bd-1);
    UBRRH=(F_CPU/8/bd-1)>>8;
    }
char USRAT_RECIEVE_CHR()
{
    while((UCSRA&(1<<RXC))==0)
    {

    }
    return UDR;
}
void USRAT_SEND_CHR(char c)
{
while((UCSRA&(1<<UDRE))==0)
{

}
 UDR=c;


}

main.c file

    #include <avr/io.h>
#define F_CPU 2000000UL
#include <util/delay.h>
#include "USRAT_TEST.h"
#include <stdio.h>
char data;
int main(void)
{
        USRAT_INIT(9600);
    /* Replace with your application code */
    while (1) 
    {
        data = USRAT_RECIEVE_CHR(); 
        USRAT_SEND_CHR(data); 
                    }
}

It's a simple simulation I added 2 virtual terminals to my AVR ....when setting U2X to 0 and writing values from datasheet when I write "a" or any character to one of them I get in the other one wrong charterer.

I took values of UBBR right from data sheet you can try without formula F_CPU/8/bd-1 and put them from table directly.

Can you tell me what is U2X effect on same BAUD RATE ???? OR When to set U2X to one or Zero??????

enter image description here


Solution

  • Look again on examples in datasheet and see how UBRR relates to baud rate and clock. You will see something like #define MYUBRR FOSC/16/BAUD-1. Your code calculates UBRR dividing clock by 8 instead of 16, so to make UART working right you have to double the clock.