Question

I am working on the serial communication of my MultiWii Pro board, which is based on a atmega2560. I am using avr-gcc to compile and avrdude to program.

Here is my problem. I am trying to get atmega2560 to send something (hex value) to the terminal. However, regardless of the value assigned to UDR2 and regardless the value I assigned to UBRR2L and UBRR2H, the terminal output is always 0xff if I set the terminal baud-rate at 9600, and 0xff if I set the terminal baud-rate at 115200.

Here is my code

#define F_CPU 8000000UL
#define BAUDRATE 19200        //The baudrate to use
#define BAUD_PRESCALLER ((F_CPU / (BAUDRATE * 16UL))-1)

static void InitializeUART()
{
    UBRR2L = (uint8_t)(BAUD_PRESCALLER);                               
    UBRR2H = (uint8_t)(BAUD_PRESCALLER>>8);
    UCSR2B |= (1<<RXEN2) | (1<<TXEN2);          //RX TX  Enable
    UCSR2C |= (1<<USBS2)|(1<<UCSZ21)|(1<<UCSZ20);
}

And my sending function

void USART2Write(char data)
{
    while( !(UCSR2A & (1<<UDRE2)));

    UCSR2B &= ~(1<<TXB82); //in the case if there are more than 8 bits of data
    if(data & 0x100)
    {
        UCSR2B |= (1 << TXB82);    
    }

    UDR2 = data;
}

In my case, the baudrate of my code is 19200. The terminal baudrate is also 19200. No matter what I assigned to UDR2, the output will always be 0x15.

Here is my fuse setting

Low     High    Extended
0xFF    0xD8    0xFD
Was it helpful?

Solution

UCSR2C |= (1<<USBS2)|(1<<UCSZ21)|(1<<UCSZ20);

USBS2 sets 2 stop bits. Is this intentional?

void USART2Write(char data){
    while( !(UCSR2A & (1<<UDRE2)));

    UCSR2B &= ~(1<<TXB82); //in the case if there are more than 8 bits of data
    if(data & 0x100) {
        UCSR2B |= (1 << TXB82);    
    }

    UDR2 = data;
}

If you really want to use 9 data bits, UCSZ22, UCSZ21 and UCSZ20 have to be set. YOu only set UCSZ21 and UCSZ20

UCSR2C |= (1<<USBS2) | (1<<UCSZ21) | (1<<UCSZ20);

so I guess that USBS2 is indeed not what you want here. Maybe you were confused because the flag UCSZ22 is in the UCSR2B register.

So assuming you want 9 data bits and one stop bit use something like this:

static void InitializeUART() {
    UBRR2L = (uint8_t)(BAUD_PRESCALLER);                               
    UBRR2H = (uint8_t)(BAUD_PRESCALLER>>8);
    UCSR2B |= (1 << RXEN2) | (1 << TXEN2) | (1 << UCSZ22);
    UCSR2C |= (1 << UCSZ21) | (1 << UCSZ20);
}

Another thing: Your variable data is of type char and char is normally 8 bit wide. So the condition if(data & 0x100) is never satisfied.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top