Errore di baud rate di una UART
Come una UART genera il baud dividendo il clock, perché nasce un errore, come si deriva il budget di tolleranza (3,95% per 8N1 a 16×) e il ruolo del divisore frazionario.
Configurare una UART è un’operazione di routine, finché un collegamento a 115200 baud, su una scheda che funziona benissimo a 9600, comincia a perdere caratteri. Quasi sempre la causa è una sola: l’errore di baud rate. Questo strumento lo calcola; questa pagina spiega da dove nasce e quando diventa un problema.
Come una UART genera il baud
Una UART non ha un oscillatore dedicato al baud: lo ricava dividendo il clock della periferica. Un generatore campiona ogni bit più volte — l’oversampling, tipicamente 16× o 8× — e un divisore porta il clock al ritmo voluto:
Il ricevitore usa l’oversampling per trovare il centro di ogni bit: rileva il fronte del bit di start, conta i tick e campiona a metà finestra, dove il segnale è più stabile.
Perché nasce l’errore
Il problema è che il divisore ideale è quasi sempre frazionario, ma il divisore intero deve essere intero. Arrotondandolo, il baud effettivamente generato si discosta dal target.
L’esempio classico: 16 MHz, 115200 baud, oversampling 16. Il divisore ideale è 16 000 000 / (16 · 115200) = 8,68. Arrotondato a 9 dà un baud reale di 16 000 000 / (16 · 9) = 111 111 baud, cioè −3,5%. Lo stesso clock a 9600 baud dà invece un divisore di ~104, arrotondato a 104 con errore quasi nullo: ecco perché la stessa scheda “funziona a 9600 ma non a 115200”.
Lo stesso baud, clock diversi
A 115200 baud e oversampling 16×, l’errore dipende interamente da quanto il divisore ideale è vicino a un intero — cioè dal clock:
| Clock | div ideale | div intero | baud intero | errore intero | div 1/16 | errore 1/16 |
|---|---|---|---|---|---|---|
| 3,6864 MHz | 2,0000 | 2 | 115 200 | 0,000 % | 2,0000 | 0,000 % |
| 8,0000 MHz | 4,3403 | 4 | 125 000 | +8,507 % | 4,3125 | +0,644 % |
| 12,0000 MHz | 6,5104 | 7 | 107 143 | −6,994 % | 6,5000 | +0,160 % |
| 14,7456 MHz | 8,0000 | 8 | 115 200 | 0,000 % | 8,0000 | 0,000 % |
| 16,0000 MHz | 8,6806 | 9 | 111 111 | −3,549 % | 8,6875 | −0,080 % |
| 18,0000 MHz | 9,7656 | 10 | 112 500 | −2,344 % | 9,7500 | +0,160 % |
| 24,0000 MHz | 13,0208 | 13 | 115 385 | +0,160 % | 13,0000 | +0,160 % |
| 25,0000 MHz | 13,5634 | 14 | 111 607 | −3,119 % | 13,5625 | +0,006 % |
| 48,0000 MHz | 26,0417 | 26 | 115 385 | +0,160 % | 26,0625 | −0,080 % |
| 72,0000 MHz | 39,0625 | 39 | 115 385 | +0,160 % | 39,0625 | 0,000 % |
Il clock da 8 MHz è il peggiore: con un divisore intero così piccolo, un solo passo di arrotondamento vale l’8,5 %. Salendo di clock il divisore cresce e ogni unità di arrotondamento pesa meno; col quarzo “da seriale” a 14,7456 MHz l’errore sparisce del tutto.
Da dove viene la soglia, calcolata
Un frame UART è start + 8 bit dati + stop = 10 bit. Il ricevitore si sincronizza sul fronte di start e poi campiona “alla cieca”, contando i bit successivi al ritmo del proprio clock. La differenza di ritmo fra i due estremi si accumula bit dopo bit lungo il frame, e la soglia si ricava da qui invece di essere assunta.
Il ricevitore campiona il bit k a (k − 0,5) periodi di bit propri dopo il fronte di start rilevato, e quel campione deve cadere dentro la finestra del bit k del trasmettitore, larga un periodo di bit. C’è poi un errore iniziale: il fronte di start viene rilevato con la risoluzione di un tick di oversampling, cioè 1/S di bit. Al primo ordine, detto e l’errore combinato fra i due estremi e n il numero di bit del frame contando start e stop:
dove q = 1/S se la decisione si prende su un solo campione, e q = 2/S se si prende a maggioranza su tre campioni consecutivi — il caso normale, che chiede un tick in più di margine sul lato verso cui si sta derivando.
| Formato | n bit | 16× (1 campione) | 16× (maggioranza) | 8× (1 campione) | 8× (maggioranza) |
|---|---|---|---|---|---|
| 7N1 | 9 | 5,15 % | 4,41 % | 4,41 % | 2,94 % |
| 8N1 | 10 | 4,61 % | 3,95 % | 3,95 % | 2,63 % |
| 8N1 + parità | 11 | 4,17 % | 3,57 % | 3,57 % | 2,38 % |
| 9N1 | 11 | 4,17 % | 3,57 % | 3,57 % | 2,38 % |
| 9 bit + parità | 12 | 3,80 % | 3,26 % | 3,26 % | 2,17 % |
Il numero da ricordare è il 3,95 % della riga 8N1 a 16× con decisione a maggioranza: è il budget totale, quello che deve coprire tutto insieme — generatore di baud del trasmettitore, generatore del ricevitore, tolleranza dei due clock sorgente, jitter.
Dove finisce il campione, bit per bit
Lo stesso conto letto come deriva accumulata sull’ultimo bit di un 8N1 a 16× (9,5 periodi di bit dal fronte di start, più 0,125 bit di quantizzazione dello start):
| Errore combinato | Deriva sull’ultimo bit | Più lo start | Campione |
|---|---|---|---|
| 0,5 % | 0,048 bit | 0,172 bit | dentro |
| 1,0 % | 0,095 bit | 0,220 bit | dentro |
| 2,0 % | 0,190 bit | 0,315 bit | dentro |
| 3,0 % | 0,285 bit | 0,410 bit | dentro |
| 4,0 % | 0,380 bit | 0,505 bit | FUORI |
| 5,0 % | 0,475 bit | 0,600 bit | FUORI |
Il mezzo bit si esaurisce fra il 4 % e il 5 %, non al 5 %: a 4 % il campione è già a 0,505 bit dal centro, cioè appena oltre il bordo. È anche la lettura più utile del perché i guasti da baud sono intermittenti: il bit che cede per primo è sempre lo stop, e un frame che sbaglia lo stop alza un framing error, non un byte corrotto silenzioso. Se invece l’errore è grosso, la deriva raggiunge anche i bit dati e allora arrivano byte sbagliati senza nessun flag.
Una cosa che l’accumulo non fa è propagarsi fra frame: ogni fronte di start riazzera il conteggio, quindi l’errore non cresce con la lunghezza del messaggio. Un errore del 3 % rompe un frame su molti, in modo casuale, e non “peggiora andando avanti”.
Il budget si divide fra i due estremi
Se entrambi gli estremi stanno entro il 2 % ma in direzioni opposte, la differenza è il 4 %: oltre il budget di 3,95 %. Ecco allora cosa significano davvero i colori dello strumento — il verde sotto il 2 % non è prudenza, è il massimo allocabile a un estremo assumendo che l’altro sia praticamente esatto. La banda ambra 2–3 % è la zona in cui il collegamento funziona se l’altro capo è buono, e il rosso oltre il 3 % non lascia margine a nessuno.
E il generatore di baud non è l’unico a consumare budget: prima di lui c’è la tolleranza del clock sorgente, contata due volte perché gli estremi sono due.
| Sorgente di clock ai due estremi | Tolleranza sommata | Resta al generatore di baud |
|---|---|---|
| TCXO ±2,5 ppm | 0,0005 % | 3,95 % |
| quarzo ±50 ppm | 0,010 % | 3,94 % |
| RC interno calibrato ±1 % | 2,000 % | 1,95 % |
| RC interno ±2 % | 4,000 % | −0,05 % |
L’ultima riga è il motivo per cui una scheda senza quarzo dialoga a 9600 e non a 115200 pur avendo un errore di generatore nullo: due RC interni non calibrati a ±2 % consumano da soli l’intero budget. Con un quarzo, invece, del budget resta praticamente tutto al generatore — ed è quel caso che lo strumento misura.
Oversampling 16× contro 8×
A 16× ogni bit è osservato su 16 tick e la decisione si prende a maggioranza attorno al centro: massima robustezza a rumore e jitter. A 8× il divisore può dimezzarsi, quindi con lo stesso clock si raggiungono baud più alti — ma con metà del margine di campionamento. La regola pratica: 16× di default, 8× solo quando serve spremere l’ultimo fattore due di velocità.
Il prezzo esatto è nella tabella sopra, sulla riga 8N1: si passa da un budget di 3,95 % a 2,63 %, cioè si perde un terzo della tolleranza. In cambio si raddoppia il baud massimo — a 48 MHz il divisore minimo 1 dà 3 Mbaud a 16× e 6 Mbaud a 8×. È uno scambio ragionevole solo se il collegamento è corto e i clock sono a quarzo: mettere 8× su un RC interno vuol dire chiedere 2,63 % di budget a una catena che ne consuma già 2 di sola tolleranza.
Il divisore frazionario
Molti peripherali moderni (per esempio la USART degli STM32) non usano un divisore intero ma una mantissa più una frazione su 4 bit, cioè passi di 1/16. Quantizzando la parte frazionaria del divisore ideale a 1/16, il baud reale si avvicina moltissimo al target.
Nel caso 16 MHz / 115200: il divisore ideale 8,68 viene rappresentato come 8 + 11/16 = 8,6875, che dà un baud di 115 108 — errore −0,08% invece di −3,5%. Il divisore frazionario è il rimedio standard quando il clock non si può scegliere libero.
Il rimedio però ha un limite quantificabile, e non è quello che si crede. Quantizzando a 1/16 l’errore residuo sul divisore è al massimo mezzo passo, 1/32, e in relativo quel mezzo passo pesa tanto meno quanto più grande è il divisore:
| Baud (clock 48 MHz) | div ideale | Limite 1/(32·div) | Errore 1/16 reale |
|---|---|---|---|
| 9600 | 312,5000 | ±0,010 % | 0,000 % |
| 115 200 | 26,0417 | ±0,120 % | −0,080 % |
| 460 800 | 6,5104 | ±0,480 % | +0,160 % |
| 921 600 | 3,2552 | ±0,960 % | +0,160 % |
| 2 000 000 | 1,5000 | ±2,083 % | 0,000 % |
Quindi il divisore frazionario è efficacissimo dove il divisore è grande (baud bassi) e smette di bastare dove serve di più: a 2 Mbaud su 48 MHz il divisore ideale è 1,5 e il limite teorico è già ±2,08 %, dentro la banda ambra. Le colonne «reale» sono spesso molto migliori del limite — se il divisore ideale casca vicino a un multiplo di 1/16 l’errore è zero — ma il limite è quello che va usato per decidere se un baud è raggiungibile in modo robusto o solo per fortuna aritmetica.
Scegliere il clock giusto
I clock “magici” per la seriale sono multipli interi di (baud · oversampling). A 16× un clock di 14,7456 MHz dà errore zero su tutta la famiglia 9600–921600, perché 14 745 600 / 16 = 921 600 esatti, e 921600 è multiplo di tutti i baud standard. Sono i quarzi dall’aria strana (3,6864 / 7,3728 / 14,7456 / 22,1184 MHz) che esistono apposta per la seriale. Se il clock è vincolato da altro (USB a 48 MHz, PLL di sistema), il divisore frazionario recupera il margine.
Limiti
- La quantizzazione frazionaria qui è a 1/16 (4 bit), il caso più comune; alcuni peripherali hanno risoluzione diversa o vincoli aggiuntivi (in 8× il bit meno significativo della frazione è trattato a parte).
- Si considera il solo errore del generatore di baud: non sono modellati la tolleranza del clock sorgente (quarzo o PLL) né il jitter, che si sommano e mangiano parte del margine del ±2–3%.
- Strumento dimostrativo: per la configurazione reale valgono il reference manual della UART e i suoi registri (BRR, OVER8, campi mantissa/frazione).
Riferimenti
- Reference manual del peripherale UART/USART — il documento che definisce il calcolo del divisore, i campi del registro baud rate, l’oversampling e l’eventuale divisore frazionario per quel MCU. È il riferimento operativo.
- Strumento correlato — il calcolatore di errore baud UART mette in pratica questa pagina: inserisci clock, baud, oversampling e frazionario e leggi divisore, baud reale, errore e la tabella dei baud standard.
Un progetto simile?
Acustica, embedded, strumenti di calcolo: se hai un caso d’uso vicino, parliamone.