Go Down

Topic: Minor bug in duino's bootloader (Read 3119 times) previous topic - next topic


ATmegaBOOT_168.c (from 0017)

Code: [Select]
#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)

     UCSR0A = (1<<U2X0); //Double speed mode USART0
     UBRR0L = (uint8_t)(F_CPU/(BAUD_RATE*8L)-1);
     UBRR0H = (F_CPU/(BAUD_RATE*8L)-1) >> 8;
     UBRR0L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
     UBRR0H = (F_CPU/(BAUD_RATE*16L)-1) >> 8;

16 bits register high part always have to be written BEFORE low part. Here luck makes it work since the high byte is actually zero.

Coding Badly

There's no mention of this in the ATmega168 documentation.  Please provide a reference.


8-bit Microcontroller with 4/8/16/32K Bytes In-System Programmable Flash
ATmega48PA ATmega88PA ATmega168PA ATmega328P

Rev. 8161C-AVR-05/09

?      Bit 11:0 - UBRR11:0: USART Baud Rate Register
This is a 12-bit register which contains the USART baud rate. The UBRRnH contains the four most significant bits, and the UBRRnL contains the eight least significant bits of the USART baud rate. Ongoing transmissions by the Transmitter and Receiver will be corrupted if the baud rate is changed. Writing UBRRnL will trigger an immediate update of the baud rate prescaler.

This is in line with other registers in the timers and so forth.


Dec 23, 2009, 10:07 pm Last Edit: Dec 23, 2009, 10:08 pm by borref Reason: 1
There is a section in the manual "15.3 Accessing 16-bit Registers" with details on potential issues with 16-bit register access (additional restrictions apply also to reading the 10-bit ADC value). I'm not sure however how this would apply to the baud rate register.

One thing to note is that the compiler will handle 16-bit register access correctly if we allow it to. Rather than reading/writing the two 8-bit registers individually it is better practice to read/write through the 16-bit reference in a single C statement. For the baud register this would be along the following lines:

Code: [Select]

 if (nonu2x_baud_error > u2x_baud_error) {
   UCSR0A = 1 << U2X0;
   UBRR0 = F_CPU / (8 * baud) - 1;
 } else {
   UCSR0A = 0;
   UBRR0 = F_CPU / (16 * baud) - 1;

UBRR0 above is the 16-bit reference to the baud rate divisor and the other 16-bit registers have similar defines. This is easier to read and not subject to 16-bit access issues.


While on the topic of Duino bootloader "issues" - here's another:

Code: [Select]
/* the current avr-libc eeprom functions do not support the ATmega168 */
/* own eeprom write/read functions are used instead */
#if !defined(__AVR_ATmega168__) || !defined(__AVR_ATmega328P__)
#include <avr/eeprom.h>

The "#if" above will always be true and so irrespective of target mcu (168/328 or whatever), the avr/eeprom.h file will always be included. Perhaps it was left in the source as a reminder, but I can't see a purpose beyond that.

Coding Badly


I have Arduino S3V3 R2 and cannot understand how to download the sketch into it. and also what about bootloader? I need interface information and bootloader information and software. Please tell me what should I do?

Coding Badly

Did you purchase the processor with the bootloader already installed?


No. I am using layout and then I want to make my own pcb. I am purchasing the atmega8 or atmega168. but I don't know how to download my sketch

Coding Badly

Then you will need to install the bootloader.  I believe there are instructions here...

Go Up