Search code examples
cavruartusart

USART transmission - AVR (atmega169p) receives 0 or null instead of char 'a'


I'm trying to send a character 'a' with termite to my AVR via a USB-to-serial cable. This has worked before, but after a while atmel studio didn't show the controller as a device, I had to update atmel studio to a later version to recognize the controller. I probably changed the code somewhere along the way to try so I'm not sure if the code is correct anymore.

It's a really simple program for receiving the first char that arrives:

#include <avr/io.h>
#include "initialize.h"
#include "constantComfort.h"

char receivedchar;

void USART_receive_char(void){
    /* wait for data to be received */
    while( !(UCSR0A & (1<<RXC0)) );

    receivedchar = UDR0;
}

int main(void)
{
    init(0.5); //0.5 for interruptcycle in seconds
    USART_receive_char();
    writeLong(receivedchar,1);
}

The write-long can write 'a' as the ascii-code 97 if I insert it directly, but when I try to receive 'a' or other chars it just shows 0.

The initialization of the AVR looks like this, and I am pretty sure I have set the termite-program accordingly. 9600 BAUD, 8 data-bits, 1 stop-bit, no parity.

//USART (for Serial connection to computer)
    #define F_CPU       1000000
    #define BAUDRATE    9600                            // 9600 bits/sec
    #define BAUD        ((F_CPU)/(BAUDRATE*16UL)-1)     // from formula

    /* enable USART0 module */
    PRR = (0<<PRUSART0);

    /* set baud rate to  defined baudrate*/
    UBRR0H = (BAUD>>8);
    UBRR0L = (BAUD);

    /* enable receiver and transmitter */
    UCSR0B |= (1<<RXEN0)|(1<<TXEN0);

    /* set frame format: 8 data bits, 1 stop bit (always 1 start bit)*/
    UCSR0C |= (0<<USBS0)|(3<<UCSZ00);

I am rather sure that this is all the code that affects this problem. I have gone through the manual for register names so I believe the initialization is correct.

Anyone have an idea what to do with this problem?


Solution

  • atmega169p has 8 MHz clock-frequency

    I had read that in "low power consumption" mode the avr will have a clock-frequency of 1 MHz and somehow thought it was the default.

    By default atmega169p has 8 MHz clock frequency without prescaling, so the baud calculation is wrong and I assume the avr didn't read fast enough because of this, thereby receiving '0'.

    Correct code snippet:

        //USART (for Serial connection to computer)
        #define F_CPU       8000000 //>>>>>>>>>>  THIS ONE!  <<<<<<<<<<<<
        #define BAUDRATE    9600                            
        #define BAUD        ((F_CPU)/(BAUDRATE*16UL)-1)     
    

    Changing to 8 MHz like in this code snippet solved my problem.

    Thanks for the help with other potential problems in my code!