What is the maximum clock difference between a transmitter and receiver for error-free asynchronous serial communication?
Electronic – the maximum acceptable baud rate error for RS-232 serial communication
baudraters232serial
Related Solutions
At least three reasons, probably:
- In the era when RS-232 ports were common, it so by far the most common means of bit-at-a-time communication, so much so that the term "serial port" became synonymous with "RS-232 port"; using the term "serial" in connection with anything else would add confusion. Note that USB avoids such confusion mainly because it seldom referred to as "Universal Serial Bus", so the existence of the word "serial" in its long-form name is a non-issue.
- In nearly all cases, RS-232 ports their logic-level equivalents transmit individual bytes as they are received from software, and individual incoming bytes available to software as they are received. By contrast, most Ethernet devices will wait until software has supplied an entire packet (between 64 and 1536 bytes) before they begin transmission, and will wait until they have received and validated an entire packet before they make any of it available to software. Although bits and bytes might be sent over the wire serially, software neither knows nor cares. It just knows that some short time after one controller is fed a packet and told to send it, another controller will report that a packet is available, and allow software to read it.
- A "serial port" is guaranteed to transmit bytes of data in the chronological sequence that software supplies them, and make them available to software in the chronological sequence they are received; it would be rather useless if it did not. All Ethernet and Internet systems guarantee that when a packet is sent from one node to another the arrangement of bytes made available to the recipient will match the arrangement of bytes supplied by the sender, but there is no common specification requiring that the chronological order in which data are transmitted have any relation to their arrangement within a packet. Further, there only guarantees that can be made with regard to chronological sequencing of packets relative to each other are highly vague. If packet X is delivered Sunday at 11:47am and packet Y is delivered the next day at 3:28pm, one can safely assume that Y was sent after X. On the other hand, if X is delivered at 1:47:12 and Y is delivered at 1:47:15, it's entirely possible that Y was sent first but X took longer to arrive.
Incidentally, a 10-base-T Ethernet connection sends individual bits in sequence, but higher-speed cabling often uses various signalling methods to send multiple bits at once.
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
Feel free to edit in more values. These are the ones I'm using now.
Atmel ATmega UART:
NXP LPC111x (Cortex-M0) UART: 1.1% (no table)
Microchip PIC 18F2XK20/4XK20: not defined. (wtf.)
As the venerable Mr. Horowitz & Hill put it:
Note that conductor length plays a large part in serial clock errors. I stay under 19200 baud for regular ribbon cable more than 2' long. Makes me jealous of 4' 60Gb/s USB lines.