According to the datasheet I'm setting the UCSR0C register as following:

UCSR0C = 0b00000110


Bit   0:   0: TX rising, RX falling
Bit 2-1:  11: character size 8 bit
Bit   3:   0: 1 stop bit
Bit 5-4:  00: no parity
Bit 7-6:  00: asynchronous USART

(http://www.atmel.com/images/doc2545.pdf page 193)

Although I configured the UART to use 8 bit data mode I have to set my communicating terminal (picocom) to use 7 bit data mode. Otherwise I don't get correct data from my ATmega168. I also tried to use minicom and miniterm.py.

My target device I want to communicate with is a Raspberry Pi. I'm using Peter Fleury's UART library (http://homepage.hispeed.ch/peterfleury/group__pfleury__uart.html).

Any ideas what I'm be doing wrong? Did I forget something?

  • \$\begingroup\$ Can you show how you set your baud rate? What does your ATmega168 run at, Mhz-wise? Is it running on internal oscillator or external crystal? Maybe show the fuse settings from avrdude? What is your F_CPU set to? \$\endgroup\$ Mar 17, 2013 at 4:49

2 Answers 2


Could it be that UCSZ02 bit in UCSR0B is set? This would give you 9-bit character size... It also could be a matter of incorrect baud selection, including the cases where your MCU does not run at the speed you are expecting: the set baud rate is sensitive to MCU clock speed.

In general, I would recommend using |, & and << operators to set your register bits: it looks cleaner, and much easier to understand what is going on. Thus, personally, I would rewrite your register assignment as:

UCSR0C = 0
    | (0<<UMSEL01) | (0<<UMSEL00)   // Asynchronous USART
    | (0<<UPM01) | (0<<UPM00)       // Parity Disabled
    | (0<<USBS0)                    // 1 stop bit
    | (1<<UCSZ01) | (1<<UCSZ00)     // 8-bit character size
    | (0<<UCPOL)                    // Rising TX, falling RX

But this is not what you asked about, and this is clearly a matter of taste.

  • \$\begingroup\$ Thank you for your advices. I did use the common notation in my code. I wrote it like 0b00000110 in my question to safe space. I also checked UCSZ02 if UCSR0B is set but it isn't. My baud rate is set to 9600 on both sides. As I said, I get correct data when I set my target device to 7 bit data mode, as long as I transmit 7 bit data. \$\endgroup\$
    – arminb
    Mar 17, 2013 at 4:52
  • \$\begingroup\$ Ah, cool. In addition to the baud rate selection code, I think it would be good to see how UCSR0A and UCSR0B are set, just in case. \$\endgroup\$ Mar 17, 2013 at 4:55

I solved the problem by using an external oscillator. It seems that the internal oscillator is too imprecise for UART communication.

  • \$\begingroup\$ Hmmm.. that shouldn't be the case if F_CPU is set right. Is it possible that you had the 8x clock divider set (it is on by default), and you were thinking that you were running at 8mhz when you were actually at 1mhz? I could imagine that when you were burning the fuses for the external oscillator you'd turn CKDIV8 fuse off, but perhaps it was on before? I mean, I've done serial with internal oscillator with no problems. \$\endgroup\$ Mar 17, 2013 at 22:36
  • \$\begingroup\$ I definately had CKDIV8 set off before. My F_CPU was 8 MHz. \$\endgroup\$
    – arminb
    Mar 17, 2013 at 22:41
  • 1
    \$\begingroup\$ That's strange: according to the datasheet, at 8mhz and 9600 baud you should have only about 0.2% error in the baud rate, whether U2Xn is set or not. The datasheet claims +/-10% factory calibration of the internal oscillator, so perhaps this is what we are seeing: 10% clock error seems significant enough to affect serial comms. Good to know: I'll keep this in mind. \$\endgroup\$ Mar 17, 2013 at 22:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.