Why serial communication does not work on atmega168/328p?
The problem you have is that your baud rate is not being set right.

You only have part of the settings you need.  There is a third macro in the setbaud.h file that you need to take account of:  USE_U2X.

That defines whether or not you need to set or clear the U2X0 bit of UCSRA0.  If that is set wrong then your baud rate will be either twice or half what you want it to be - in this case it's coming out as twice.

Modify your code to assign the baud rate like this:

#include &lt;util/setbaud.h&gt; 
UBRR0H = UBRRH_VALUE;
UBRR0L = UBRRL_VALUE;
#if USE_U2X
UCSR0A |= (1&lt;&lt;U2X0);
#else
UCSR0A &amp;= ~(1&lt;&lt;U2X0);
#endif
UCSR0B |= (1&lt;&lt;RXEN0);
UCSR0C |= (1&lt;&lt;UCSZ01)|(1&lt;&lt;UCSZ00);


Then you should be able to receive characters.

In the actual header file in question there is a large number of comments and instructions, including this:


  Assuming that the requested BAUD is valid for the given F_CPU then
     the macro UBRR_VALUE is set to the required prescaler value.  Two
     additional macros are provided for the low and high bytes of the
     prescaler, respectively: UBRRL_VALUE is set to the lower byte of
     the UBRR_VALUE and UBRRH_VALUE is set to the upper byte.  An
     additional macro USE_2X will be defined.  Its value is set to 1 if
     the desired BAUD rate within the given tolerance could only be
     achieved by setting the U2X bit in the UART configuration.  It will
     be defined to 0 if U2X is not needed.


My resulting UART configuration, which may be being affected by the bootloader, is:

UBRR0H: 0x00
UBRR0L: 0x67
UCSR0A: 0x20
UCSR0B: 0x10
UCSR0C: 0x06


That equates to data register empty, RX enabled, 8-bit.

To my mind that is equal to the values being manually set in the code, so shouldn't be a problem.