0
\$\begingroup\$

I'm working with an Atmega328p, running off the internal 8MHz oscillator, divided by 8 to produce a 1MHz clock. I set the fuses according to the calculator here. Confirming this with avrdude:

avrdude -p m328p -c usbasp avrdude: warning: cannot set sck period. please check for usbasp firmware update. avrdude: AVR device initialized and ready to accept instructions Reading | ################################################## | 100% 0.00s avrdude: Device signature = 0x1e950f (probably m328p) avrdude: safemode: Fuses OK (E:FF, H:D9, L:62) 

The timing seems to be correct - blinking an led on and off every 1000 ms takes ca. 1 second, as expected.

I am confused when it comes to setting up serial communication to my computer. No matter what I try, the connection is set to 1200. The program I'm using is:

#include <avr/io.h> #include <util/delay.h> #include <USART.h> int main(void) { DDRB |= 0b0000001; initUSART(); while (1) { printString("\n\r==== Looping ====\n\r"); PORTB = 0b00000001; _delay_ms(750); PORTB = 0b00000000; _delay_ms(250); } return (0); } 

Where USART is from Elliott Willams' book. It includes the following:

#include <avr/io.h> #include "USART.h" #include <util/setbaud.h> void initUSART(void) { /* requires BAUD */ UBRR0H = UBRRH_VALUE; /* defined in setbaud.h */ UBRR0L = UBRRL_VALUE; #if USE_2X UCSR0A |= (1 << U2X0); #else UCSR0A &= ~(1 << U2X0); #endif /* Enable USART transmitter/receiver */ UCSR0B = (1 << TXEN0) | (1 << RXEN0); UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); /* 8 data bits, 1 stop bit */ } // more code follows, not included here 

My Makefile generates the following commands:

avr-gcc -Os -g -std=gnu99 -Wall -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -ffunction-sections -fdata-sections -DF_CPU=1000000UL -DBAUD=9600UL -I. -I../../AVR-Programming-Library -mmcu=atmega328p -c -o blinkLED.o blinkLED.c avr-gcc -Wl,-Map,blinkLED.map -Wl,--gc-sections -mmcu=atmega328p blinkLED.o ../../AVR-Programming-Library/USART.o -o blinkLED.elf avr-objcopy -j .text -j .data -O ihex blinkLED.elf blinkLED.hex avrdude -c usbasp -p atmega328p -P /dev/ttyACM0 -U flash:w:blinkLED.hex 

Baud is set in the Makefile, in this case to 9600UL. If I set it to 19200UL, everything works the same. In either case, everything behaves as it should, but when I connect to the serial line from my computer (via screen /dev/ttyUSB0), the output is garbled unless I specify BAUD = 1200. (i.e., screen /dev/ttyUSB0 1200).

I've been struggling through a bunch of webpages, the Williams book, and the atmega datasheet, but I'm still not getting this. Is the baud rate fixed for this chip? If not, how do I set it to a rate higher than 1200?

At this point I actually need to set it any higher, but I'd like to understand how this is supposed to work, and what I'm getting wrong.

Update

Note that I have explicitly set BAUD and F_CPU with the avr-gcc flags: -DF_CPU=1000000UL -DBAUD=9600UL. Even if I set these macros in the code (as #define BAUD 9600UL and #define F_CPU 1000000UL as the first lines in the file, I'm still stuck with BAUD of 1200.

Update 2

I have isolated the problem to the setbaud.h file. If I set the baud rate 'by hand', that is, using the following code in place of the call to initUSART(); above, it works as expected - the BAUD is correctly set to 9600. This sets the prescaler to 12 (0b00001100) and enables USE_2X. So my problem must be that I'm using setbaud.h improperly, but I can't see how.

UBRR0H = 0; UBRR0L = 0b00001100; UCSR0A |= (1 << U2X0); /* Enable USART transmitter/receiver */ UCSR0B = (1 << TXEN0) | (1 << RXEN0); UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); /* 8 data bits, 1 stop bit */ 
\$\endgroup\$
0

1 Answer 1

1
\$\begingroup\$

As the comments suggest, you have to define BAUD in the setbaud.h file. Here it says you have to define F_CPU before including setbaud.h file. (That's because setbaud.h uses some macros to calculate UBR0 values based on your required baud rate and operating CPU speed)

\$\endgroup\$
1
  • \$\begingroup\$ Those macros are set via flags to avr-gcc - see my edit above. Adding explicit define statements at the top of my c code doesn't change the baud rate? \$\endgroup\$ Commented Mar 16, 2016 at 15:44

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.