Minor bug in duino's bootloader

ATmegaBOOT_168.c (from 0017)

#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)

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

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.

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.

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:

  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:

/* 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>
#endif

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.

Got it. Thanks!

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?

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

Then you will need to install the bootloader. I believe there are instructions here... http://arduino.cc/en/Hacking/Bootloader?from=Main.Bootloader