If I remember correctly, the 8051 will ignore any character which is received with an invalid stop bit (detected framing error). If characters are being sent back-to-back, it's possible for an arbitrary number of characters to have framing errors unless the data stream contains a FF, FE, FC, F8, F0, E0, C0, 80, or 00 (the nine characters which, if written in binary, do not contain the bit sequence "01"). Those nine characters may be received incorrectly, but the characters following them will be received correctly).
Addendum
A standard UART will drive its transmit line high when idle, until data is supposed to be sent. It will then drive the line low for precisely one bit time (called the "start bit"), then send (typically) eight bits of data, LSB first, for precisely one bit time each, and drive the line high for a minimum of one bit time (called the "stop bit") before sending the next byte (which will result in precisely one bit time low, then the data bits, etc.)
When a UART's receiver is idle, it will wait for a high-low transition. When one is seen, it will check the data line half a bit time later to ensure the line is still low; if not, it will go back to idle state. If the data line was still low at that point, it will then sample the data line nine more times, at one-bit-time intervals. The first eight of these will be latched as the eight data bits. The ninth sample (which should occur during the transmitted stop bit) should be high. If it isn't, either there was noise on the line when the stop bit was being transmitted or (more likely) the receiver was triggered by a high-low transition other than the start bit; this condition is called a framing error.
The stop bit serves two purposes:
- It ensures that the next transmitted byte of data will begin with a high-low transmission;
- It provides an opportunity for the receiver to detect framing errors.
Note that depending upon the precise data being transmitted, it's possible that framing errors might not be detected, and that different UARTs will behave differently when they do occur. The 8051 reacts to framing errors by simply pretending that a mis-framed byte was not received at all, behavior which is really not terribly helpful. Some other UARTs will record, for each byte, whether it was received with correct or incorrect framing; others will set a flag when a framing error occurs, and the flag will remain set until the processor explicitly clears it, the idea being that when one is receiving a bunch of data, a framing error during a single byte will likely imply that much of the data is corrupt.
When framing errors occur, the receiver may not be able to function correctly until a pattern of data occurs on the line which will allow it to get back into sync. The best pattern for this purpose, which will work with essentially all receivers, is a data byte "FF". This byte will be sent with a single high-low transition (indeed, with only a single "low" bit--the start bit). If the receiver was out of sync when the byte is transmitted, its start bit may be mistakenly identified as a data bit from an earlier byte, but all of its data bits and the stop bit will be regarded as idle time between bytes. The next high-low transition on the line will be the start bit of the next character (as it should be).
PS--On many UART receive circuits, any of the byte values I listed will work to allow reception to get back in sync with transission. Some, however, will regard a "0" bit that's received where a stop bit should have been to be the start bit for the next byte. The value "FF" should work for any UART receive circuit, however.
To understand all of this stuff, take a look at "Table 18-1. Equations for Calculating Baud Rate Register Setting" from the datasheet on page 189. The equation you suggested you found in some example code
UBRR1 = (F_CPU / 4 / baud - 1) / 2;
... is kind of close to the equation for Asynchronous Double Speed mode (U2Xn = 1)... but not exactly.
If you know the baud rate and crystal speed you intend to operate at, I would just pull the register settings out of "Table 18-9. Examples of UBRRn Settings for Commonly Used Oscillator Frequencies" on datasheet page 210 and call it a day. The only reason to use any of those equations is if you want to be able to change the settings dynamically at run-time for some reason (or if you want to do thins "elegantly" in software, I prefer compile time certainty for something like this to remove doubt).
For the settings you outlined in your question, that would be:
UCSR1A = 0; // importantly U2X1 = 0
UCSR1B = 0; // interrupts enabled in here if you like
UCSR1C = _BV(UCSZ11) | _BV(UCSZ10); // no parity, 8 data bits, 1 stop bit
UCSR1D = 0; // no cts, no rts
UBRR1 = 103; // 9600 baud @ 16MHz XTAL with U2X1 = 0
As a side note, while the hardware does store the baud rate register (UBBRn) as two 8-bit registers, in software there is no need to treat it as such. You can access the High and Low registers (e.g. UBRR1H and UBRR1L respectively) but you can also just
assign to (or read from) the named "combined" register as though it was a 16-bit register.
UBRR1 = 0x0343;
is functionally equivalent to UBRR1H = 0x03; UBRR1L = 0x43;
Best Answer
There are some great formulas on page 178 of the datasheet that describe the baud generator and how to calculate the divisors to get the USART clock rate that you want.
There are also some nice examples of baud rate settings on page ~200. The examples for the 1MHz case are here:
Be careful to conduct your error calculations too, as some baud divisors aren't close enough to the desired frequency and may not work for you when you are trying to use the UART. Generally, I try to get within +/-2.5% or so when setting up the baud generator on these parts.
At 1MHz you might be trying to use the internal RC clock source with the CLKDIV8 fuse programmed. That's not a good idea when trying to set up USART communications on these parts. The RC oscillator performance is not good across voltage and temperature. The internal RC oscillator tolerance on these parts is pretty bad and is not good enough to hold UART communications without errors.
Here's the data in the datasheet about the internal RC oscillator performance across voltage and temperature. You'll notice that stacking the errors up can yield some pretty bad tolerances on the final RC oscillator values:
To get it working, you will need to use an external clock source or go through some calibration procedures as described in these app notes. If you know your voltage and temperature won't move around much, you can gradually move the value in the OSCCAL to a value that does work, but that will be different from part-to-part and isn't a great production solution if you are making lots of devices. If you are going to try that, be sure to follow the guidelines in the datasheets and app notes. Changing the value in OSCCAL too much at once can disturb the oscillator and cause problems.
http://www.atmel.com/Images/doc2563.pdf http://www.atmel.com/Images/doc8002.pdf
Good luck - have fun setting it up and getting it working.