Articles

Terug naar de basis: De Universele Asynchrone Ontvanger/Transmitter (UART)

In dit technische artikel worden enkele low-level details van de wijdverbreide – ik zou zelfs zeggen alomtegenwoordige – UART communicatie-interface uitgelegd.

Relatieke informatie

  • Gezellige, robuuste gegevensoverdracht met RS-422 en RS-485

Er zijn waarschijnlijk maar weinig elektrotechnici en elektronicaliefhebbers in de wereld die niet op de een of andere manier te maken hebben gehad met een universele asynchrone ontvanger/transmitter (UART)-interface. In een wereld waarin technologie zeer snel verouderd kan raken, moeten we eer betonen aan degene die dit eenvoudige digitale communicatieschema heeft bedacht, dat al tientallen jaren bestaat en nog steeds een immense populariteit geniet.

Note: De term “UART” is nogal vaag. Verschillende aspecten van de interface – aantal databits, aantal stopbits, logische niveaus, pariteit – kunnen worden aangepast aan de behoeften van het systeem. In dit artikel zal ik me richten op UART-implementaties die veel voorkomen in moderne microcontroller-toepassingen.

Mogelijkheden en kenmerken

Zoals u waarschijnlijk weet, biedt een basis UART-systeem robuuste, full-duplex communicatie met gemiddelde snelheid en slechts drie signalen: Tx (verzonden seriële gegevens), Rx (ontvangen seriële gegevens), en aarde. In tegenstelling tot andere protocollen, zoals SPI en I2C, is er geen kloksignaal nodig omdat de gebruiker de UART-hardware de benodigde timing-informatie geeft.

Eigenlijk is er wel een kloksignaal, maar dit wordt niet van het ene communicerende apparaat naar het andere verzonden; in plaats daarvan hebben zowel ontvanger als zender interne kloksignalen die bepalen hoe de veranderende logische niveaus worden gegenereerd (aan de Tx-zijde) en geïnterpreteerd (aan de Rx-zijde). Het zal geen verbazing wekken dat UART-communicatie niet werkt als de zender en ontvanger zijn geconfigureerd voor verschillende data-overdrachtsfrequenties. Ook moeten de interne kloksignalen 1) voldoende nauwkeurig zijn ten opzichte van de verwachte frequentie en 2) voldoende stabiel in tijd en temperatuur.

Key Terms

Laten we eens wat terminologie doornemen en daarbij meer UART karakteristieken behandelen:

  • Start bit: Het eerste bit van een UART-transmissie van één byte. Het geeft aan dat de datalijn zijn rusttoestand verlaat. De idle-toestand is meestal logisch hoog, dus het startbit is logisch laag.
    • Het startbit is een overheadbit; dit betekent dat het de communicatie tussen ontvanger en zender vergemakkelijkt, maar geen zinvolle gegevens overdraagt.
  • Stopbit: Het laatste bit van een UART-transmissie van één byte. Het logicaniveau is hetzelfde als de rusttoestand van het signaal, d.w.z. logisch hoog. Dit is een ander overheadbit.

  • Baud-rate: De snelheid bij benadering (in bits per seconde, of bps) waarmee gegevens kunnen worden overgedragen. Een nauwkeuriger definitie is de frequentie (in bps) die overeenkomt met de tijd (in seconden) die nodig is om één bit digitale gegevens over te brengen. Bijvoorbeeld, bij een 9600-baud systeem is voor één bit 1/(9600 bps) ≈ 104,2 µs nodig. Het systeem kan in werkelijkheid geen 9600 bits aan zinvolle gegevens per seconde overdragen, omdat extra tijd nodig is voor de overheadbits en misschien voor vertragingen tussen de transmissies van één byte.

  • Pariteitsbit: Een bit voor foutdetectie die aan het einde van een byte wordt toegevoegd. Er zijn twee soorten: “oneven pariteit” betekent dat de pariteitsbit logisch hoog is als de gegevensbyte een even aantal logisch hoge bits bevat, en “even pariteit” betekent dat de pariteitsbit logisch hoog is als de gegevensbyte een oneven aantal logisch hoge bits bevat. Dit kan contra-intuïtief lijken, maar het idee is dat het pariteitsbit ervoor zorgt dat het aantal logic-high bits altijd even (voor even pariteit) of oneven (voor oneven pariteit) is. Dus als je even pariteit gebruikt en de byte heeft drie logic-high bits, dan zal het pariteitsbit logic-high zijn, zodat het totale aantal logic-high bits in de verzonden gegevens (d.w.z,
    • Doordat het aantal logische hoge bits altijd even (voor even pariteit) of oneven (voor oneven pariteit) is, biedt de pariteitsbit een ruw mechanisme voor foutdetectie: als ergens in het transmissieproces een bit wordt omgedraaid, komt het aantal logische hoge bits niet overeen met de gekozen pariteitsmodus. Natuurlijk gaat deze strategie stuk als twee bits worden omgedraaid, dus de pariteitsbit is verre van kogelvrij. Als je echt foutloze communicatie wilt, raad ik je een CRC aan.

Synchronisatie en Sampling

Standaard digitale data is zinloos zonder een of ander klokmechanisme. Het volgende schema laat zien waarom:

Een typisch datasignaal is eenvoudigweg een spanning die overgaat tussen logisch laag en logisch hoog. De ontvanger kan deze logische toestanden alleen correct omzetten in digitale gegevens als hij weet wanneer hij het signaal moet bemonsteren. Dit kan eenvoudig worden bereikt door gebruik te maken van een apart kloksignaal-bijvoorbeeld, de zender werkt het datasignaal bij op elke opgaande flank van de klok, en de ontvanger bemonstert de data op elke neergaande flank.

Zoals de naam “universele asynchrone ontvanger/zender” al aangeeft, maakt de UART interface echter geen gebruik van een kloksignaal om de Tx en Rx apparaten te synchroniseren. Hoe weet de ontvanger dan wanneer hij het datasignaal van de zender moet bemonsteren?

De zender genereert een bitstroom op basis van zijn kloksignaal, en het doel van de ontvanger is vervolgens zijn interne kloksignaal te gebruiken om de binnenkomende gegevens in het midden van elke bitperiode te bemonsteren. Bemonstering in het midden van de bitperiode is niet essentieel, maar wel optimaal, omdat bemonstering dichter bij het begin of einde van de bitperiode het systeem minder robuust maakt tegen klokfrequentieverschillen tussen ontvanger en zender.

De ontvanger-sequentie begint met de neergaande flank van het startbit. Dit is het moment waarop het kritieke synchronisatieproces plaatsvindt. De interne klok van de ontvanger is volledig onafhankelijk van de interne klok van de zender – met andere woorden, deze eerste neergaande flank kan overeenkomen met elk punt in de klokcyclus van de ontvanger:

Om ervoor te zorgen dat een actieve flank van de ontvangerklok zich in het midden van de bitperiode kan voordoen, is de frequentie van de baud-rate klok die naar de ontvangermodule wordt gezonden veel hoger (met een factor 8 of 16 of zelfs 32) dan de werkelijke baud-rate.

Laten we zeggen dat één bitperiode overeenkomt met 16 klokcycli van de ontvanger. In dat geval kunnen synchronisatie en sampling als volgt verlopen:

  1. Het ontvangstproces wordt gestart door de neergaande flank van het startbit.
  2. De ontvanger wacht 8 klokcycli, om een samplingpunt vast te stellen dat zich in de buurt van het midden van de bitperiode bevindt.
  3. De ontvanger wacht dan 16 klokcycli, waarmee hij in het midden van de eerste data-bitperiode komt.
  4. De eerste databits worden gesampled en opgeslagen in het ontvangstregister, en vervolgens wacht de module nog eens 16 klokcycli voordat de tweede databits worden gesampled.
  5. Dit proces herhaalt zich totdat alle databits zijn gesampled en opgeslagen, en dan keert de opgaande flank van de stopbit de UART-interface terug naar zijn rusttoestand.

Conclusie

Dit artikel heeft enkele details behandeld over een communicatieprotocol dat u misschien al vele malen met succes hebt gebruikt. Het is heel goed mogelijk om een UART interface te implementeren terwijl u heel weinig weet over het werkelijke gedrag van de signalen en hardware, maar een beetje extra kennis – naast de algemene opvoeding die dergelijke kennis biedt – kan nuttig zijn wanneer uw UART communicatie niet werkt zoals verwacht.

Laat een antwoord achter

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *