Articles

Ritorno alle basi: L’Universal Asynchronous Receiver/Transmitter (UART)

Questo riassunto tecnico spiega alcuni dettagli di basso livello dell’interfaccia di comunicazione UART, diffusa – potrei anche dire onnipresente.

Informazioni correlate

  • Trasmissione dati comoda e robusta con RS-422 e RS-485

Probabilmente sono pochi gli ingegneri elettrici e gli appassionati di elettronica che non hanno interagito in qualche modo con un’interfaccia UART (Universal Asynchronous Receiver/Transmitter). In un mondo in cui la tecnologia può diventare obsoleta molto rapidamente, dobbiamo dare credito a chi ha creato questo semplice schema di comunicazione digitale, che esiste da decenni e gode ancora di immensa popolarità.

Nota: Il termine “UART” è piuttosto vago. Vari aspetti dell’interfaccia – numero di bit di dati, numero di bit di stop, livelli logici, parità – possono essere adattati alle esigenze del sistema. In questo articolo, mi concentrerò sulle implementazioni UART che si trovano comunemente nelle moderne applicazioni per microcontrollori.

Capacità e caratteristiche

Come probabilmente sapete, un sistema UART di base fornisce una comunicazione robusta, a velocità moderata e full-duplex con solo tre segnali: Tx (dati seriali trasmessi), Rx (dati seriali ricevuti) e terra. A differenza di altri protocolli come SPI e I2C, non è richiesto alcun segnale di clock perché l’utente fornisce all’hardware UART le informazioni di temporizzazione necessarie.

In realtà, c’è un segnale di clock, ma non viene trasmesso da un dispositivo comunicante all’altro; piuttosto, sia il ricevitore che il trasmettitore hanno segnali di clock interni che governano come i livelli logici variabili sono generati (sul lato Tx) e interpretati (sul lato Rx). Non sorprende che la comunicazione UART non funzioni se il trasmettitore e il ricevitore sono stati configurati per frequenze di trasmissione dati diverse. Inoltre, i segnali di clock interni devono essere 1) sufficientemente accurati rispetto alla frequenza prevista e 2) sufficientemente stabili nel tempo e nella temperatura.

Termini chiave

Ripercorriamo un po’ di terminologia e, nel processo, copriremo altre caratteristiche UART:

  • Bit iniziale: Il primo bit di una trasmissione UART a un byte. Indica che la linea dati sta lasciando il suo stato di inattività. Lo stato di inattività è tipicamente logicamente alto, quindi il bit di inizio è logicamente basso.
    • Il bit di inizio è un bit di overhead; questo significa che facilita la comunicazione tra ricevitore e trasmettitore ma non trasferisce dati significativi.
  • Bit di stop: L’ultimo bit di una trasmissione UART a un byte. Il suo livello logico è lo stesso dello stato di inattività del segnale, cioè logico alto. Questo è un altro bit di overhead.

  • Baud rate: La velocità approssimativa (in bit al secondo, o bps) alla quale i dati possono essere trasferiti. Una definizione più precisa è la frequenza (in bps) corrispondente al tempo (in secondi) necessario per trasmettere un bit di dati digitali. Per esempio, con un sistema a 9600 baud, un bit richiede 1/(9600 bps) ≈ 104,2 µs. Il sistema non può effettivamente trasferire 9600 bit di dati significativi al secondo perché è necessario del tempo aggiuntivo per i bit di overhead e forse per i ritardi tra le trasmissioni di un byte.

  • Bit di parità: Un bit di rilevazione degli errori aggiunto alla fine del byte. Ci sono due tipi: “parità dispari” significa che il bit di parità sarà logicamente alto se il byte di dati contiene un numero pari di bit logico-alto, e “parità pari” significa che il bit di parità sarà logico alto se il byte di dati contiene un numero dispari di bit logico-alto. Questo può sembrare controintuitivo, ma l’idea è che il bit di parità assicura che il numero di bit logico-alto sia sempre pari (per la parità pari) o dispari (per la parità dispari). Quindi se stai usando la parità pari e il byte ha tre bit logico-alti, il bit di parità sarà logico alto, in modo che il numero totale di bit logico-alti nei dati trasmessi (cioè il byte stesso più il bit di parità) è pari.
    • Facendo in modo che il numero di bit logico-alti sia sempre pari (per la parità pari) o dispari (per la parità dispari), il bit di parità fornisce un rozzo meccanismo di rilevamento degli errori: se un bit viene capovolto da qualche parte nel processo di trasmissione, il numero di bit logico-alti non corrisponderà al modo di parità scelto. Naturalmente, la strategia si rompe se due bit vengono capovolti, quindi il bit di parità è tutt’altro che a prova di bomba. Se hai un serio bisogno di una comunicazione senza errori, ti consiglio un CRC.

Sincronizzazione e campionamento

I dati digitali standard non hanno senso senza un meccanismo di clock di qualche tipo. Il seguente diagramma mostra il perché:

Un tipico segnale dati è semplicemente una tensione che passa tra basso logico e alto logico. Il ricevitore può convertire correttamente questi stati logici in dati digitali solo se sa quando campionare il segnale. Questo può essere facilmente realizzato utilizzando un segnale di clock separato – per esempio, il trasmettitore aggiorna il segnale dati su ogni fronte di salita del clock, e poi il ricevitore campiona i dati su ogni fronte di discesa.

Tuttavia, come implica il nome “ricevitore/trasmettitore asincrono universale”, l’interfaccia UART non utilizza un segnale di clock per sincronizzare i dispositivi Tx e Rx. Quindi come fa il ricevitore a sapere quando campionare il segnale dati del trasmettitore?

Il trasmettitore genera un flusso di bit basato sul suo segnale di clock, e poi l’obiettivo del ricevitore è di usare il suo segnale di clock interno per campionare i dati in arrivo nel mezzo di ogni periodo di bit. Il campionamento a metà del periodo di bit non è essenziale, ma è ottimale, perché il campionamento più vicino all’inizio o alla fine del periodo di bit rende il sistema meno robusto contro le differenze di frequenza di clock tra il ricevitore e il trasmettitore.

La sequenza del ricevitore inizia con il fronte di caduta del bit iniziale. Questo è il momento in cui avviene il processo critico di sincronizzazione. Il clock interno del ricevitore è completamente indipendente dal clock interno del trasmettitore – in altre parole, questo primo fronte di caduta può corrispondere a qualsiasi punto del ciclo di clock del ricevitore:

Per garantire che un fronte attivo del clock del ricevitore possa verificarsi vicino alla metà del periodo di bit, la frequenza del clock di baud-rate inviato al modulo ricevitore è molto più alta (di un fattore di 8 o 16 o anche 32) rispetto al baud rate effettivo.

Diciamo che un periodo di bit corrisponde a 16 cicli di clock del ricevitore. In questo caso, la sincronizzazione e il campionamento possono procedere come segue:

  1. Il processo di ricezione è iniziato dal fronte di discesa del bit di inizio.
  2. Il ricevitore attende 8 cicli di clock, per stabilire un punto di campionamento che sia vicino alla metà del periodo di bit.
  3. Il ricevitore attende quindi 16 cicli di clock, che lo portano alla metà del primo periodo di bit di dati.
  4. Il primo bit di dati viene campionato e memorizzato nel registro di ricezione, e poi il modulo attende altri 16 cicli di clock prima di campionare il secondo bit di dati.
  5. Questo processo si ripete fino a quando tutti i bit di dati sono stati campionati e memorizzati, e poi il fronte di salita del bit di stop riporta l’interfaccia UART al suo stato inattivo.

Conclusione

Questo articolo ha coperto alcuni dettagli su un protocollo di comunicazione che forse avete usato con successo molte volte. È abbastanza possibile implementare un’interfaccia UART sapendo molto poco del comportamento effettivo dei segnali e dell’hardware, ma un po’ di conoscenza in più – a parte l’edificazione generale che tale conoscenza fornisce – può essere utile quando la vostra comunicazione UART non funziona come previsto.

Lascia una risposta

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *