Komunikujeme UART

V minulém díle jsme si ukázali příklad toho, ja jednoduše měřit napětí procesorem AVR. Využili jsme toho, že procesor má rozhraní pro odesílání dat sériovou linkou (UART). Dnes si popíšeme jak s ním pracovat. Jedná se totiž o periferii hojně využívanou...

USART

USART, neboli Univerzal Synchronous and Asynchronous Receiver and Transmitter je obvod schopný obousměrné komunikace rychlostmi jednotek až desítek kbaud. Umožňuje jak synchronní, tak asynchronní přenos s možností nastavení 5 - 9 datových bitů, nastavení počtu stop-bitů a parity. Umožňuje samozřejmě také multiprocesorovou komunikaci.

S obvody UARTu se můžeme setkat i na základních deskách běžného PC. Dříve se jednalo o samostatné desky, dnes jsou již součástí čipsetu.

Jak už bylo uvedeno výše, budeme toto rozhraní čile využívat a to nejen pro komunikaci s ostatními procesory, ale také při komunikaci s PC. Je to totiž ta nejschůdnější cesta. Mnozí výrobci uvedli už před několika lety na trh převodníky USART/USB, takže není problém vyrobit si vlastní zařízení komunikující přes USB rozhraní. To se hodí zvláště při napojení na notebook.


Základní popis

Jednotka USART je složena ze tří hlavních bloků. Z vysílače, přijímače a generátoru hodin.

Generátor hodin slouží pro generování synchronizačních signálů. V procesorech 8051 je místo tohoto generátoru používán jeden z časovačů/čítačů, čímž se o jeden připravíme. V tomto případě nám však všechny běžné čítače / časovače zůstanou k účelnému využití.

Vysílač a přijímač obsahují buffery pro vysílání a příjem bajtů. Je-li obvod správně nastaven, je možné odvysílat bajt pouhým zápisem do bufferu. Po odvysílání celého bajtu je nastaven příznak TXC v registru UCSRA. Při příjmu je nastaven bit RXC registru UCSRA. Musíme ale dávat pozor na to, že příznaky jsou čitelné pouze jednou. Po přečtení jsou automaticky nulovány.

Režimy

Jednotka USART může pracovat celkem ve čtyřech režimech:
  • asynchronní režim
  • asynchronní režim s dvojnásobnou rychlostí
  • synchronní master
  • synchronní slave
Ke komunikaci s PC používáme samozřejmě jeden z prvních dvou režimů, pokud nemáme žádný zvláštní důvod, využíváme raději režim první. Nemusíme zde tak dbát na přesnost nastavené přenosové rychlosti. K nastavení dvojnásobné přenosové rychlosti stačí nastavit bit U2X registru UCSRA.

Mezi synchronním a asynchronním režimem volíme nastavením bitu UMSEL (nastaveno pro synchronní). V tomto případě také určujeme zdroj hodinového signálu a to bitem DDRB0, který najdeme v registru DDRB. Hodinový signál je poté přiváděn (nebo odváděn) pinem XCK.

Použití jednotky USART

Jak už bylo napsáno výše, je možné jednotku pro sériový přenost používat v několika režimech. Z toho důvodu je nutné ji před použitím správně nastavit. Příprava sestává z nastavení přenosového rámce (počet datových bitů, parita, počet stop-bitů) a z nastavení přenosové rychlosti. Před použitím musí být samozřejmě jednotka spuštěna (zvlášť příjem a zvlášť vysílání)

Registry pro řízení sériového rozhraní

UDR - registr pro čtení a zápis.

Pokud je povoleno vysílání nastavením bitu TXEN z registru UCSRB, zapsáním bajtu do registru dojde k jeho přesunutí do bufferu vysílače. Před použitím je ale nutné samozřejmě nastavit režim přenosu (počet bitů, parita, atd...)
Než přesuneme další bajt do registru, je nutné testovat, zda je předchozí bajt odvysílán. To provedeme testováním příznaku UDRE registru UCSRA. Bit je vynulován, pokud je vysílací posuvný registr prázdný. Tento test musí být proveden vždy!!! Vyjímkou jsou situace, kdy využíváme přerušení.

Pro vysílání devítibitových znaků, platí zvláštní podmínky. Nebudeme je zde probírat. Ale v datasheetu naleznete podrobnější informace.

Pokud je povolen bit RXEN registru UCSRB, je možné přijímat sériovou linkou znaky. Z přijímacího bufferu jsou znaky přesouvány do registru UDR. Kompletně přijatý znak je indikován nastaveným bitu RXC registru  UCSRA.

Registr UCSRA



RXC - nastavením indikuje přijatý bajt
TXC - nastaví se při odeslání bajtu (a žádná jiná data nejsou v bufferu)
URDE - nastaví se, když je vysílací buffer prázdný
FE - chyba rámce
DOR - ztráta dat
PE - chybná parita
U2X - nastavením tohoto registru můžeme zvolit dvojnásobnou přenosovou rychlost. Je ale nutné přesněji nastavit registry UBRR.
MPCM - nastavení víceprocesorového režimu - vysvětleno v úvodu


Registr UCSRB



RXCIE
- povolí přerušení od příjmu. Je-li bit nastaven, vyvolá se po dokončení příjmu znaku přerušení na adrese URXCaddr.
TXCIE - povolí přerušení od vysílače. Přerušení je vyvoláno nastavením příznaku TXC.
UDRIE - povolí přerušení.od vysílače. Přerušení je vyvoláno nastavením příznaku UDRE.
RXEN - povolení příjmu
TXEN - povolení vysílání
UCSZ2 - nastavení délky znaku viz tabulka níže
RXB8 - devátý bit znaku (příjem)
TXB8 - devátý bit znaku (vysílání)

Registr UCSRC



URSEL
- výběr mezi zápisem do registru UCSRC nebo UBBRH (registry mají společný adresní prostor). Je-li bit nastaven, pak se pracuje s UCSRC.
UMSEL - je-li bit nastaven, jedná se o synchronní přenos. Je-li bit nulován, jedná se o asynchronní přenos.
UPM1, UPM0 - parita

    0      0      BEZ PARITY
    0      1      rezervováno
    1      0      sudá
    1      1      lichá

USBS
- je-li bit nastaven vysílají se dva stop-bity. Je-li vynulován, vysílá se stop-bit jeden.

UCSZ2 : UCSZ0 -
počet datových bitů

    0      0      0      5 b
    0      0      1      6 b
    0      1      0      7 b
    0      1      1      8 b
    1      0      0      rezervováno
    1      0      1      rezervováno
    1      1      0      rezervováno
    1      1      1      9 b

UCPOL
- je-li USART nastaven pro synchronní režim, určuje bit, zda budou data vzorkována sestupnou nebo vzestupnou hranou

Pro nastavení přenosové rychlosti slouží registry UBRRH a UBBRL Hodnota těchto registrů pro asynchronní režim se spočítá podle následujícího vzorce:



Nyní už známe vše potřebné pro to, abychom si mohli napsat jednoduchý program pro práci se sériovým portem...


      .NOLIST
      .INCLUDE"m16def.inc"
      .LIST
      .DEF REG=R16
      .DEF REG2=R17
 
      LDI   REG2,$00
     
      LDI   REG,LOW(RAMEND)
      OUT   SPL,REG
      LDI   REG,HIGH(RAMEND)
      OUT   SPH,REG
 
      CLR   REG
      OUT   DDRC,REG   
      SER   REG
      OUT   PORTC,REG  
 
      LDI R16,LOW(0)
      OUT UCSRA,R16
      ; povolení vysílače a příjímače
      LDI R16,(1<<TXEN)|(1<<RXEN)
      OUT UCSRB,R16
      ; nastavení počtu datových bitů
     
LDI R16,(1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1)
      OUT UCSRC,R16
      ; nastavení přenosové rychlosti
     
LDI R16,LOW(0)
      OUT UBRRH,R16
      LDI R16,LOW(95)
      OUT UBRRL,R16
 
SMYCKA:
 
      SBIS PINC,PINC0
      RCALLWRITE_UP
      SBIS PINC,PINC1
      RCALLWRITE_DOWN
      SBIS PINC,PINC7
      RCALLWRITE_ENTER
 
      RJMP SMYCKA
 
UP:    .DB       "UP",$00,$00
DOWN:  .DB       "DOWN",$00,$00
ENTER: .DB       "ENTER",$00
 
 
WRITE_UP:
      LDI   REG,LOW(2*UP)
      LDI  REG2,HIGH(2*UP)
      RCALLWRITE_STRING
      RET
 
WRITE_DOWN:
      LDI   REG,LOW(2*DOWN)
      LDI  REG2,HIGH(2*DOWN)
      RCALLWRITE_STRING
      RET
 
WRITE_ENTER:
      LDI   REG,LOW(2*ENTER)
      LDI  REG2,HIGH(2*ENTER)
      RCALLWRITE_STRING
      RET
 
 
WRITE_STRING:
      MOV   ZL,REG
      MOV   ZH,REG2
      LDI   REG2,$00
CYKL:
      LPM   REG,Z+
      CPSE REG,REG2
      RJMP DAL
      RJMP KONEC_ZAPISU
DAL:
      RCALLVYSLANI_DAT
      RJMP CYKL
 
KONEC_ZAPISU:
      RET
 
 
;podprogram zápisu byte na UART
VYSLANI_DAT:
 sbisUCSRA,udre
 rjmpVYSLANI_DAT
 out udr,REG
RET
 
 
Uzemňováním pinů PC0, PC1, PC7 (například tlačítkem, jsou přes USART vysílány řetězce "UP", "DOWN", "ENETER". (9600, 1, 1, N)
V příkladu jsme si zopakovali i práci s konstantami v paměti programu. Je-li Vám cokoliv z toho nejasného, pište prosím do komentářů pod článkem. Vaše dotazy rád zodpovím. Pouze připomínám, že program je odladěn na krystalu 14.7456 Mhz. Samozřejmě není problém přepočítat hodnotu registru UBRR pro jiný krystal.

Komentovat článek

Jméno:  
Zpráva:

Komentáře k článku

Ondřej Karas - 28.8.2007 15:45

Na první pohled v tom nevidím žádnej problém. Jestliže vysílání funguje tak jak má (správně spočítaná přenosová rychlos) a je povolen příjem (což jak jsem z úryvku zdrojáku pochopil, tak je), nevidím důvod k tomu aby to nechodilo. Doporučuji odsimulovat v AVR Studiu. Jinak bych asi doporučil použít knihovní fce překladače, kde funkce na čtení znaku jsou.

standa - 28.8.2007 07:17

Vysílání jsem zvládl, ale mám problém s přijmem. Procesor at90s2313 UART komunikuje s MT Siemens s 35 pomocí AT příkazů. Nazpět bych měl dostat OK nebo něco jiného.Bohužel se zacyklím při čtení.viz příklad //************************************************ // UART initialization // Communication Parameters: 8 Data, 1 Stop, No Parity // UART Receiver: On // UART Transmitter: On // UART Baud rate: 19200 //************************************************ UCR=0x18; UBRR=0x0C; while ( !(USR & (RX_COMPLETE))); pombuf[pocc++] = UDR; mohl byste pomoci?