serial-bench / calculators
The two sums I run before touching a bus, taped to a page so I stop re-deriving them: a UART baud-error budget from two reference clocks, and an I²C rise time from pull-up and bus capacitance. Both run in your browser and send nothing; with scripts off, the formula and a reference table under each one give the same answer by hand.
A classic UART divides its reference clock by sixteen and then by an integer, so it can only
produce f / (16 × N). Rounding N leaves an error. Two ends work only if
their combined error stays well inside half a bit cell over a frame - the hard ceiling is
0.5 / 9.5 = 5.26 %, and I refuse anything above 4 %. Full write-up:
the seven-per-cent baud error.
N = round(f / (16 × baud)), actual = f / (16 × N),
error = (actual − baud) / baud. Add the magnitudes of the two ends.
| Reference | 9600 | 57600 | 115200 |
|---|---|---|---|
| 8 MHz | +0.16 % | −3.55 % | +8.51 % |
| 11.0592 MHz | 0.00 % | 0.00 % | 0.00 % |
| 12 MHz | +0.16 % | +0.16 % | −7.00 % |
| 16 MHz | +0.16 % | +2.12 % | −3.55 % |
| 18.432 MHz | 0.00 % | 0.00 % | 0.00 % |
The pull-up resistor charges the bus capacitance through an RC curve. The time from 0.3 to
0.7 of the supply is t = ln(0.7 / 0.3) × R × C = 0.847 × R × C, and it must stay
under the limit for the bus speed. Full write-up:
310 pF and the rise time I ignored.
t_rise = 0.847 × R × C, with R in ohms and C in farads. Lower the resistor to
speed the edge; the floor is the current the open-drain output can sink, roughly
V_DD / R.
| R \ C | 100 pF | 220 pF | 310 pF | 400 pF |
|---|---|---|---|---|
| 1.0 kΩ | 85 | 186 | 263 | 339 |
| 1.8 kΩ | 152 | 335 | 473 | 610 |
| 2.2 kΩ | 186 | 410 | 578 | 745 |
| 4.7 kΩ | 398 | 876 | 1234 | 1593 |