Aszinkron soros kommunikáció (UART)

A fejezet tartalma:

Amikor egy mikrovezérlő a külvilággal kommunikál, az adatforgalom többnyire bájtok, vagy több bájból álló üzenetcsomagok formájában történik.

Párhuzamos kommunikáció esetén minden adatbitet külön adatvonalon  küldünk ki, s a kommunikáció szinkronizálásához még néhány vezérlő jel továbbítása is kellhet. Ilyen kommunikáció zajlott hajdanában a személyi számítógépek és a Centronics kábel túlsó végén lógó nyomtató, vagy lapszkenner között.

Soros kommunikáció esetén viszont az adatbitek egymás után, szekvenciálisan kerülnek kiküldésre ugyanazon az egy adatvezetéken. Ez nem csupán gazdaságosabbá teszi a kommunikáció hardveres megvalósítást, hanem olyan típusú kommunikációt is lehetővé tesz, amelynek ellenoldali partnere nagyobb távolságban van (az ipari telephely túlsó szegletében, esetleg egy másik városban...


Az MKL25Z128VLK4 mikrovezérlő számos kommunikációs perifériával rendelkezik:
Ezek közül most az UART kommunikációs egységek használatával ismerkedünk meg, a többi perefériára majd a későbbi fejezetekben kerül sorra.

Univerzális aszinkron soros kommunikáció

Az univerzális aszinkron soros adatküldés és fogadás története a géptávírók koráig nyúlik vissza. Fő feladata az volt, hogy a párhuzamos adatokat (egy-egy karakter 5, 7, vagy 8 bites kódja) egyetlen vonalon, adatbitenként időben egymás után küldje el egy előre megszabott ütemben (pl. 110 bit/s), a vevő oldalon pedig a soros adatokat vissza kell állítani karakterkódokká. A kapcsolat jellegétől függően a kommunikáció lehet egyirányú (simplex), felváltva kétirányú (half duplex), vagy egyidejűleg kétirányú (full duplex). A teletype az első miniszámítógépek általános perifériájaként is kitűnő eszköz volt. Az első UART áramkörök a DEC PDP miniszámítógépeihez készültek, amelyekben a bejövő jel mintavételezésével jobb időzítést sikerült megvalósítani, mint a korábbi eszközökkel.

Az aszinkron soros kapcsolat egyik fontos jellemzője, hogy nincs külön szinkronjel, ezért az adónak és a vevőnek előre rögzített ütemben (bitrátával) kell küldeni/fogadni az adatokat. A másik fontos jellemző pedig az, hogy az adatbájtok (vagy karakterek) "keretbe foglalva" kerülnek kiküldésre. Erre egyrészt azért van szükség, hogy a végtelen bitfolyamban meg lehessen találni az egyes adategységeket, másrészt minden újabb adatbájt kezdete lehetőséget ad az újraszinkronizálásra.    

A keretezés azt jelenti, hogy minden adatbájt előtt van egy start bit, az adatbájt után pedig egy (vagy két) stop bit. A start és stop bit között adatküldési formátumtól függően lehet 5, 7, 8 vagy 9 adatbit és opcionálisan egy paritásbit. Mi a legelterjedtebb 8, N, 1 formátumot fogjuk használni, azaz 8 adatbitet küldünk, nem használunk paritásbitet, s a stop bitek száma 1 lesz. Egy tipikus jelalak (a TX kimenet jelszintjének időbeli lefutása) az alábbi ábrán látható. Az ábrán látható jelsorozat a bináris 0b01001101 adatbájt (ne feledjük: visszafelé kell olvasni!), ami a hexadecimális 0x4D-nek, vagy a decimális 77-nek felel meg, s az ASCII kódtábla szerint az „M” karakter kódját jelenti.

1. ábra:  Egy tipikus UART jelalak

Az UART kommunikáció eredetileg bipoláris, NRZ (Non Return to Zero) jelszintekkel történik. Egy példa erre az RS-232 ahol a a logikai '1' jelszintje -15 V és -3 V közötti, a logikai '0' jelszintje pedig +15 V és +3 V közötti lehet. A mikrovezérlők és a logikai IC-k világában azonban természetesebb megoldás az unipoláris jelszint alkalmazása: '1' a digitális rendszer logikai  magas jelszintje (régebben +5 V, az újabb eszközöknél, és így esetünkben is +3,3 V), a '0' pedig az alacsony logikai szint (0 V). Tétlen állapotban, amikor nincs adatküldés, az adás vonalat (TX) magas szinten kell tartani. Minden elküldött karakter egy start jellel kezdődik, azaz a TX vonal egy bitidő tartamára alacsony szintre vált. Ezt követően kerülnek kiküldésre egymás után az adatbitek, a legkisebb helyiértékű bittel kezdve. A legmagasabb helyiértékű bit után egy stop bit következik, amikor egy bitidő tartamára a kimenet magas szintre vált.

Ha a vevő azt tapasztalja, hogy a stop bit helyén (ami esetünkben a 10. bitet jelenti, ami a start bit lefutó élét 9 bitidőnyi késéssel követi) alacsony szintet észlel, akkor „keretezési hibát” (Framing Error) jelez és eldobja a feltehetően hibásan vett adatot.

Egy bit időtartama az adatküldés sebességétől függ. A szabványos adatsebességek (300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200 bit/s stb) közül alapértelmezetten a 9600 bit/s-ot használjuk. A 9600 bit/s azt jelenti, hogy egy bitre 1 s/9600  = 0,00010416667 s, azaz 104,1667 µs idő jut. Vegyük észre, hogy a karakterek "keretezése" miatt a hasznos adatok továbbítási sebessége kisebb, mint az aktuális adatküldési sebesség, mivel a 8 bites adaton kívül legalább egy START és egy STOP bitet is ki kell küldenünk.

UART modulok kivezetései

Az MKL25Z128VLK4 mikrovezérlő kivezetés kiválasztás (pin multiplexing) funkciója lehetővé teszi, hogy a három UART periféria lábkivezetéseinek kiosztását több lehetőség közül kiválasszuk. Az, hogy az egyes UART modulok adó (TX) és vevő (RX) vezetéke egyáltalán mely lábakon vezethető ki,  a FRDM-KL25Z Pin usage and pinout chart dokumentumban található. Ezen lehetőségek közül némelyik a FRDM-KL25Z kártya esetében hardver ütközés miatt nem használható. A ténylegesen használható kivezetéseket az mbed forráskódjának PeripheralPins.c állománya alapján az alábbi táblázatban foglaltuk össze. A táblázatban vastagon szedett nevű kivezetések az elsődlegesen ajánlottak, amennyiben a kártya csatlakozó pontjainak Arduino kompatibilis kiosztását nem akarjuk megzavarni. A táblázatban a kivezetések megnevezés mellett zárójelben feltüntettük Zárójelben megadtuk a kivezetés üzemmódjának beállításához szükséges számot is, amit az adott kivezetéshez tartozó megfelelő PORTx_PCRn portvezérlő regiszter MUX bitcsoportjába kell beírni az UART mód kiválasztásához. Például az UART0 modulhoz tartozó PTA1 és PTA2 kivezetések engedélyezése így néz ki:
  SIM->SCGC5 |= 0x0200;   // PORTA engedélyezése
PORTA->PCR[1] = 0x0200; // PTA1 UART RX módba állítása
PORTA->PCR[2] = 0x0200; // PTA2 UART TX módba állítása
Megjegyzés: Természetesen a táblázatban szereplő számot 8 bináris helyiértékkel balra kell tolni (két hexadecimális nullát utána kell írni...), a MUX bitcsoport helyiértékének megfelelően.

1. táblázat: Az UART portok választható kivezetései
Modul
TX
RX
Megjegyzés
UART0
PTA2 (2)
PTA1  (2)
Az OpenSDA USB-UART protokol konverterhez csatlakozik
PTD7  (3)
PTD6  (3)
Alternatív kivezetési lehetőség
PTE20 (4)
PTE21 (4)
Alternatív kivezetési lehetőség
UART1
PTE0  (3)
PTE1  (3)
A Pin diagram szerinti támogatott kivezetés
PTC4  (3)
PTC3  (3)
Alternatív kivezetési lehetőség
UART2
PTE22 (4)
PTE23 (4)
A Pin diagram szerinti támogatott kivezetés
PTD3  (3)
PTD2  (3)
Alternatív kivezetési lehetőség
PTD5  (3)
PTD4  (3)
Alternatív kivezetési lehetőség
Megjegyzés: A FRDM-KL25Z kártyán a mikrovezérlő PTA1, PTA2 kivezetései egy-egy 1 kΩ ellenálláson keresztül vannak összekötve az OpenSDA eszköz USB-UART protokoll konverter TX/RX kivezetéseivel. Ez elvileg azt is lehetővé teszi, hogy "erősebb meghajtással" az OpenSDA  eszköz felől érkező adatvonal felett átvegyük az irányítást egy másik UART eszközzel. Ennek kipróbálását azonban kezdőknek nem ajánljuk, használják inkább a többi UART kivezetést!

A soros perifériák engedélyezése

Minden használni kívánt perifériát engedélyezni kell. Az MKL25Z128VLK4 mikrovezérlő soros perifériáit a SIM_SCGC4 regiszter megfelelő bitjének '1'-be állításával lehet engedélyezni.


2. ábra: A SIM_SCGC4 regiszter bitjeinek kiosztása

Az UARTx modulok regiszterkészlete

A Freescale MKL25Z128VLK4 mikrovezérlő három UART modulja hasonló regiszterkészlettel rendelkezik (az UART0 modul felépítése valamivel bonyolultabb, ezért ennek hárommal több regisztere van). A regiszterkészletek báziscímei:
Az alábbiakban az UART0 egység regiszterkészletét ismertetjük röviden. Mindegyik regiszter 8-bites.
Regiszternév
A regiszter funkciója Cím
UART0_BDH Baud Rate Register High (adatsebesség - magas helyiérték)
4006_A000
UART0_BDH Baud Rate Register Low (adatsebesség - alacsony helyiérték) 4006_A001
UART0_C1
Control Register 1 (1. vezérlő regiszter)
4006_A002
UART0_C2 Control Register 2 (2. vezérlő regiszter) 4006_A003
UART0_S1 Status Register 1 (1. állapotjelző regiszter)
4006_A004
UART0_S2 Status Register 2 (2. állapotjelző regiszter)
4006_A005
UART0_C3 Control Register 3 (3. vezérlő regiszter) 4006_A006
UART0_D Data Register (Adat regiszter)
4006_A007
UART0_MA1 Match Address Register 1 (1. címegyezés regiszter)
4006_A008
UART0_MA2 Match Address Register 2 (2. címegyezés regiszter)
4006_A009
UART0_C4 Control Register 4 (4. vezérlő regiszter) 4006_A00A
UART0_C5 Control Register 5 (5. vezérlő regiszter) 4006_A00B
Az egy-egy UART modulhoz tartozó regiszterek leegyszerűsítve három csoportba sorolhatók:
Az UART modulok vázlatos felépítését az alábbi ábrán mutatjuk be.


3. ábra: Egy UART modul felépítésének blokkvázlata

Az UART0 modul konfigurálása

Ebben a szakaszban az UART0 modul konfigurálását mutatjuk be, amely egyrészt az OpenSDA programozó és USB-UART átalakító áramkörön keresztül kitűnő lehetőséget kínál a PC-vel történő kommunikációra.

Az adatátviteli sebesség beállítása

Az adatküldő egység az adatátviteli sebességnek (Baud rate) megfelelő frekvenciájú órajelet igényel. Minden órajel impulzusra egy bit kerül kiküldésre. Mivel az UART porton az adatátvitel aszinkron módon zajlik, a vevőegységnek minél pontosabban kell tudni meghatározni a beérkező adat Start bitjének a homlokélét. Ennek érdekében a bemenet mintavételezése nem a bitrátának megfelelő frekvenciával, hanem nagyobb frekvenciájú gyakorisággal történik. Ezt túlmintavételezésnek (oversampling) nevezzük. Az UART0 modul esetén a túlmintavételezési arány tág határok között (4x - 32x) változtatható, míg az UART1 és UART2 modulok esetében a túlmintavételezés rögzített arányú: a Baud rate frekvencia 16-szorosával történik a bemenet mintavételezése.

Az adatátviteli sebesség beállítása egy frekvenciaosztó áramkör segítségével történik, melynek osztási arányát az összefogott UARTx_BDH : UARTx_BDL regiszterpárba írt 13-bites  szám adja meg (az UARTx_BDH regiszter SBR bitcsoportjába az öt legmagasabb helyiértékű bitet, az UARTx_BDL regiszterbe pedig az alsó 8 bitet kell írni). Osztási arányként 1 - 8191 közötti számot adhatunk meg. Nulla beírása esetén az UART modul adatforgalma leáll, nem érvényes osztási arány.

D7
D6
D5
D4
D3
D2
D1
D0
UART0_BDH
LBKDIE
RXEDGIE
SBNS
SBR
UART0_BDL
SBR
A frekvenciaosztó bemenetére jutó órajel UART1 és UART2 esetén mindig a periféria busz órajele, az UART0 esetében azonban többféle lehetőség közül választhatunk a SIM rendszerintegrációs modul SIM_SOPT2 regiszterének konfigurálásával. Ha új projektet hozunk létre a Keil MDK 5.20 IDE alatt, a rendszer órajele alapértelmezetten a belső oszcillátorral és FLL áramkörrel előállított 20,97 MHz lesz, amit az MCGFLLCLK választásával (PLLFLLSEL = 0, UART0SRC = 01) kapcsolhatjuk az UART0 modul órajel bemenetére.


4. ábra: UART0 órajelének előállítása


5. ábra: A SIM_SOPT2 regiszter bitkiosztása

A SIM_SOPT2 regiszter bitcsoportjai közül UART0SRC[1:0] csak az UART0 modul órajelének kiválasztására szolgál (00: órajel letiltva, 01: MCGFLLCLK vagy MCGPLLCLK/2, 10: OSCERCLK, 11: MCGIRCLK), a PLLFLLSEL bit azonban, ami az FLL vagy PLL áramkör kimenő órajelének kiválasztására szolgál (0: MCGFLLCLK, 1: MCGPLLCLK/2), más perifériák működésére is hatással lehet!

Megjegyzés: A Freescale MKL25Z128VLK4 mikrovezérlő órajelenek előállításáról és elnevezéseiről a KL25 Sub-Family Reference Manual 5. fejezetében, a SIM rendszerintegrációs modul regisztereinek szerepéről és bitkiosztásairól pedig a 12. fejezetében találunk részletes információt.

Az adatátviteli sebesség (Baud rate) az UART modul bemenő órajelének frekvenciájából, a UARTx_BDH : UARTx_BDL regiszterpárba írt SBR értékből és az OSR túlmintavételezési arányból számítható ki az alábbi képlet szerint:

Baud rate = UART modul órajel / (SBR * OSR)

Példa: 24 MHz buszfrekvencia -> 4800 baud, 16-szoros túlmintavételezéssel

SBR = 24 000 000/(4800*16) = 312.5. Ezt az értéket kerekíteni kell a legközelebbi egészre (312 vagy 313), végeredményben lesz egy kis eltérés a névleges értéktől, de az bőven belefér a tűréshatárba.

A túlmintavételezési arány megadása

Ahogy korábban említettük, az UART1 és UART2modulok esetében a túlmintavételezés mindig 16x arányú. Az UART0 modul esetében azonban 4x és 32x között változtatható. A túlmintavételezési arány eggyel csökkentett értékét az UART0_CR4 vezérlő regiszter alsó  5 bitjébe kell beírni. A regiszter többi bitjének szerepével itt nem foglalkozunk,  azokat állítsuk mindig 0 értékre! Végeredményben tehát a beállítás:  UART0_CR4  = OSR - 1;

Megjegyzések:

A vezérlő regiszterek beállítása

Az UART modul adatformátumát, működési módját, a programmegszakítások esetleges engedélyezését a vezérlő regiszterek segítségével adhatjuk meg.


D7
D6
D5
D4
D3
D2
D1
D0
UART0_CR1
LOOPS
DOZEEN
RSRC
M
WAKE
ILT
PE
PT
UART0_CR2 TIE
TCIE
RIE
ILIE
TE
RE
RWU
SBK
UART0_CR3 R8T9 R9T8 TXDIR TXINV
ORIE NEIE FEIE PEIE
UART0_CR5
TDMAE
0
RDMAE
0
0
0
BOTHEDGE
RESYNCDIS
UART0_CR4 MAEN1 MAEN2 M10 OSR
Az UART0_CR1 regiszter bitjeinek jelentése:
Az UART0_CR2 regiszter bitjeinek jelentése:

Megszakítás engedélyezés
Modul engedélyezés
Továbbiak
Az UART0_CR3 regiszter bitjeinek jelentése:
Az UART0_CR4 regiszter bitjeinek jelentése:
Az UART0_CR5 regiszter bitjeinek jelentése:
Összefoglalva:

A státuszregiszterek szerepe

A státuszregiszterek elsősorban az a szerepe, hogy jelezzék számunkra az UART port pillanatnyi állapotát, illetve bizonyos események bekövetkeztét. Néhány bit azonban az UART port beállítására szolgál, ezek a konfigurálásnál is szerepet játszanak.

D7
D6
D5
D4
D3
D2
D1
D0
UART0_S1
TTDRE
TC
RDRF
IDLE
OR
NF
FE
PF
UART0_S2 LBKDIF
RXEDGIF
MSBF
RXINV
RWUID
BRK13
LBKDE
RAF
Az UART0_S1 regiszter bitjeinek jelentése:
A fentiek közül ebben a fejezetben csak a TTDRE, illetve az RDRF jelzőbitekkel foglalkozunk.

Az UART0_S2 regiszter bitjeinek jelentése:
Az UART0_S2 regiszter konfigurálásra szolgáló bitjeit alapértelmezett (csupa nulla) állapotban hagyjuk.

Az adatküldés és -fogadás folyamata

Mikor küldhetünk adatot?
Mikor fogadhatunk adatot?

Mintaprogramok

Az alábbiakban elsősorban a Muhammad Ali Mazidi, Shujen Chen, Sarmad Naimi és Sepehr Naimi: "Freescale ARM Cortex-M Embedded Programming" c. könyc 4. fejezetének mintapéldáit ismertetjük, amelyek az Univerzális Soros Port egyszerű, lekérdezéses módban történő használatát mutatja be.

A programokon az alábbi apró változtatásokat eszközöltük:
A fentieken mellett legvégül egy olyan mintaprogramot mutatunk be, amiben a printf() illetve scanf() függvények által használt stdio ki- és bemenetet irányítjuk át az UART0 soros portra. Ez a program Joseph Yiu: The Definitive Guide to ARM® Cortex®-M0 and Cortex-M0+ Processors (2nd Ed.) c. könyvének mellékletéből való (a ch_18_2_uart_retarget_KL25Z_Keil_MDK projekt).

Program4_1: Egyszerű kiíratás az UART0 soros porton

A "Yes" szöveget küldjük ki 2 másodpercenként a FRDM-KL25Z  kártya UART0 Tx kimenetén keresztül a számítógép felé, az OpenSDA által biztosított virtuális soros portra. Használjunk valamilyen terminál emulátor programot (PUTTy.exe,  Termite, TeraTerm stb.) az üzenetek megjelenítéséhez, az alábbi beállítással:  9600 bps, 8N1, adatfolyam vezérlés nélkül. Az UART0 vevő modulját nem használjuk, így konfiguráláskor nem is engedélyezzük.
 
Alapértelmezetten a SystemInit() függvény 20.97 MHz FLL órajelet állít be.  A programban használt BDH=0, BDL=0x88, és OSR=0x0F beállításokkal körülbelül 9600 Baud lesz a sebesség.

Az UART0 soros port az MKL25Z128VLK4 mikrovezérlő PTA1 (Rx) és PTA2 (Tx) lábain keresztül kapcsolódik az OpenSDA áramkörön keresztül a PC-re, ezért az adatküldéshez az UART0 port beállítása mellett a PTA2 kivezetést is konfigurálnunk kell.

A konfigurálás lépései:
  1. Engedélyezzük az UART0 modult a SIM_SCGC4 regiszter 10. bitjének 1-be állításával.
  2. Legyen FLL az UART0 órajel forrása: SIM_SOPT2 bit27-26 = 01 és bit16 = 0.
  3. Az UART0 Tx/Rx letiltása konfigurálás előtt: UART0_C2 regiszter TE=0, RE = 0.
  4. Az UART0 bitsebesség konfigurálása UART0_BDH és UART0_BDL beírásával.
  5. Túlmintavételezés konfigurálása: OSR = 16x-hoz UART0_C4-ba írjunk 0x0F-et!
  6. Adatformátum konfigurálása: a szokásos adatformátum (1 stop bit, nincs paritás vizsgálat, 8-bites adat) konfigurálásához egyszerűen írjunk 0x00-t az UART0_C1 vezérlő regiszterbe!
  7. Engedélyezzük UART0 adóját: írjunk 0x08-at az UART0_C2 regiszterbe (TE bit = 1)!
  8. Engedélyezzük az A portot: a SIM_SCGC5 regiszter 9. bitje legyen 1!
  9. Válasszuk ki a PTA2 kivezetés Alt2 funkcióját (UART0_Tx) PORTA_PCR2 MUX=2.
Az adatküldés lépései:
  1. Vizsgáljuk a Status Register 1 (UART0_S1) TDRE bitjét és várjunk addig, amíg a küldő buffer üressé válik (TDRE = 1)!
  2. Írjuk bele a kiküldendő bájtot az UART0_D adatregiszterbe!
  3. Újabb karakter kiküldéséhez menjünk a 10. ponthoz!

1. lista: Program4_1/main.c listája
/* Program4_1
*
* "Yes" szöveget küldünk ki 2 másodpercenként a FRDM-KL25Z
* kártya UART0 Tx kimenetén keresztül a számítógép felé
* az OpenSDA által biztosított virtuális soros portra.
*
* A program forrása: Mazidi et al., Freescale ARM Cortex-M Embedded Programming
* http://www.microdigitaled.com/ARM/Freescale_ARM/Code/Ver1/Chapter4/Program4_1.txt
*/

#include <MKL25Z4.h>

void UART0_init(void);
void delayMs(int n);

int main (void) {
UART0_init(); // UART0 kimenet inicializálása
while (1) {
while(!(UART0->S1 & 0x80)); // Várunk, míg üres lesz a kimeneti buffer!
UART0->D = 'Y'; // karakter küldés
while(!(UART0->S1 & 0x80)); // Várunk, míg üres lesz a kimeneti buffer!
UART0->D = 'e'; // karakter küldés
while(!(UART0->S1 & 0x80)); // Várunk, míg üres lesz a kimeneti buffer!
UART0->D = 's'; // karakter küldés
delayMs(2000); // Várunk egy kicsit...
}
}

/* UART0 Tx inicializálása 9600 Baud átviteli sebességre
* Baudrate = UART0 clock freq / [OSR+1] / BDH:BDL
* Esetünkben 20.97 MHz / [15 + 1] / 0x00:0x88 = 9637 bps,
* ami elfogadható eltérés a névlegestol.
*/
void UART0_init(void) {
SIM->SCGC4 |= 0x0400; // UART0 periféria engedélyezése
SIM->SOPT2 |= 0x04000000; // MCGFLLCLK választása UART0 baudrate órajelnek
UART0->C2 = 0; // UART0 letiltása a konfigurálás idotartamára
UART0->BDH = 0x00; // Baudrate = 9600 bps (bit8 - bit12)
UART0->BDL = 0x88; // Baudrate = 9600 bps (bit0 - bit7)
UART0->C4 = 0x0F; // Túlmintavételezési arány = 16
UART0->C1 = 0x00; // 8-bites adatformátum
UART0->C2 = 0x08; // Adatküldés engedélyezése

SIM->SCGC5 |= 0x0200; // PORTA engedélyezése
PORTA->PCR[2] = 0x0200; // PTA2 legyen UART0_Tx üzemmódban
}

/* Késleltető függvény: Várakozás n milliszekundumig
* A CPU rendszerórajel alapértelmezett értéke 20.97152 MHz
*/
void delayMs(int n) {
int i;
int j;
for(i = 0 ; i < n; i++)
for (j = 0; j < 3500; j++) {}
}
A program futási eredménye az alábbi ábrán látható. Mivel a kiíratás során nem küldünk sorvége jelet, a végtelen ciklusban ismételt kiírások szövege tagolás nélkül, "ömlesztve" jelenik meg.


6. ábra: Program4_1 futási eredménye

Program4_2: Egyszerű karakter bevitel az UART0 soros porton

Karakterek fogadása a FRDM-KL25Z kártya UART0 Rx bemenetén. A vett karakter legalsó három bitjével az RGB LED színkomponenseinek ki- illetve bekapcsolt állapotát vezéreljük. A LED kezelése a Digitális ki- és bemenetek használata c. fejezet Program2_7 mintapéldájában leírtakhoz hasonlóan történik.  Használjunk valamilyen terminál emulátor programot (PUTTy.exe,  Termite, TeraTerm stb.) a karakterek küldéséhez, az alábbi beállítással:  9600 bps, 8N1, adatfolyam vezérlés nélkül. A kártya nem tükrözi vissza a fogadott karaktert. Ügyeljünk rá, hogy a terminál emulátor a küldött karakterekhez ne fűzzön hozzá semmilyen  sorvége jelet! Például a Termite program  Settings menüjében "Append nothing" beállítás kell. Az UART0 adó modulját most nem használjuk, így konfiguráláskor nem is engedélyezzük.
 
Alapértelmezetten a SystemInit() függvény 20.97 MHz FLL órajelet állít be.  A programban használt BDH=0, BDL=0x88, és OSR=0x0F beállításokkal körülbelül 9600 Baud lesz a sebesség.

Az UART0 soros port az MKL25Z128VLK4 mikrovezérlő PTA1 (Rx) és PTA2 (Tx) lábain keresztül kapcsolódik az OpenSDA áramkörön keresztül a PC-re, ezért az adatfogadáshoz az UART0 port beállítása mellett a PTA1 kivezetést kell konfigurálnunk. A konfigurálás lépései szinte szóról szóra megegyeznek az előző programná leírtakkal, változás csak a piros színnel megjelölt sorokban van.

A konfigurálás lépései:
  1. Engedélyezzük az UART0 modult a SIM_SCGC4 regiszter 10. bitjének 1-be állításával.
  2. Legyen FLL az UART0 órajel forrása: SIM_SOPT2 bit27-26 = 01 és bit16 = 0.
  3. Az UART0 Tx/Rx letiltása konfigurálás előtt: UART0_C2 regiszter TE=0, RE = 0.
  4. Az UART0 bitsebesség konfigurálása UART0_BDH és UART0_BDL beírásával.
  5. Túlmintavételezés konfigurálása: OSR = 16x-hoz UART0_C4-ba írjunk 0x0F-et!
  6. Adatformátum konfigurálása: a szokásos adatformátum (1 stop bit, nincs paritás vizsgálat, 8-bites adat) konfigurálásához egyszerűen írjunk 0x00-t az UART0_C1 vezérlő regiszterbe!
  7. Engedélyezzük UART0 vevőjét: írjunk 0x04-et az UART0_C2 regiszterbe (RE bit = 1)!
  8. Engedélyezzük az A portot: a SIM_SCGC5 regiszter 9. bitje legyen 1!
  9. Válasszuk ki a PTA1 kivezetés Alt2 funkcióját (UART0_Rx) PORTA_PCR1 MUX=2.
Az adatfogadás lépései:
  1. Vizsgáljuk a Status Register 1 (UART0_S1) RDRF bitjét és várjunk addig, amíg a karakter érkezik a bufferbe (amíg RDRF = 1 nem lesz)!
  2. Olvasuk ki a vett karaktert az UART0_D adatregiszterből!
  3. Újabb karakter fogadásához menjünk a 10. ponthoz!

2. lista: Program4_2/main.c listája
/* Program4_2
*
* Karakter fogadása terminál emulátorból (PUTTy.exe,
* Termite, TeraTerm stb.) OpenSDA által biztosított virtuális
* soros porton kereeztül, a FRDM-KL25Z kártya UART0 Rx
* bemenetén. A vett karakter legalsó bitjeivel az RGB LED
* állapotát vezéreljük.
*
* A program forrása: Mazidi et al., Freescale ARM Cortex-M Embedded Programming
* http://www.microdigitaled.com/ARM/Freescale_ARM/Code/Ver1/Chapter4/Program4_2.txt
*/

#include <MKL25Z4.h>

void UART0_init(void); // UART0 Rx bemenet inicializálása
void LED_init(void); // RGB LED inicializálása

int main (void) {
char c;
UART0_init(); // UART0 Rx bemenet inicializálása
LED_init(); // RGB LED inicializálása
while (1) {
while(!(UART0->S1 & 0x20)); // Adatbeérkezésre várunk
c = UART0->D; // Kiolvassuk a vett karaktert
if (c & 1) PTB->PCOR = 0x40000; // Piros LED: BE (bit18 = 0)
else PTB->PSOR = 0x40000; // Piros LED: KI (bit18 = 1)
if (c & 2) PTB->PCOR = 0x80000; // Zöld LED: BE (bit19 = 0)
else PTB->PSOR = 0x80000; // Zöld LED: KI (bit19 = 1)
if (c & 4) PTD->PCOR = 0x02; // Kék LED: BE (bit1 = 0)
else PTD->PSOR = 0x02; // Kék LED: KI (bit1 = 0)
}
}

/* UART0 Rx inicializálása 9600 Baud átviteli sebességre
* Baudrate = UART0 clock freq / [OSR+1] / BDH:BDL
* Esetünkben 20.97 MHz / [15 + 1] / 0x00:0x88 = 9637 bps,
* ami elfogadható eltérés a névlegestol.
*/
void UART0_init(void) {
SIM->SCGC4 |= 0x0400; // UART0 periféria engedélyezése
SIM->SOPT2 |= 0x04000000; // MCGFLLCLK választása UART0 baudrate órajelnek
UART0->C2 = 0; // UART0 letiltása a konfigurálás idotartamára
UART0->BDH = 0x00; // Baudrate = 9600 bps (bit8 - bit12)
UART0->BDL = 0x88; // Baudrate = 9600 bps (bit0 - bit7)
UART0->C4 = 0x0F; // Túlmintavételezési arány = 16
UART0->C1 = 0x00; // 8-bites adatformátum
UART0->C2 = 0x04; // Adatfogadás engedélyezése

SIM->SCGC5 |= 0x0200; // PORTA engedélyezése
PORTA->PCR[1] = 0x0200; // PTA1 legyen UART0_Rx üzemmódban
}

/* RGB LED inicializálása Program2_7 alapján */
void LED_init(void) {
SIM->SCGC5 |= 0x400; // Port B engedélyezése
SIM->SCGC5 |= 0x1000; // Port D engedélyezése
PORTB->PCR[18] = 0x100; // PTB18 legyen GPIO (MUX = 1)
PTB->PDDR |= 0x40000; // PTB18 legyen kimenet (bit18)
PTB->PSOR = 0x40000; // Piros LED lekapcsolása (negatív logika!)
PORTB->PCR[19] = 0x100; // PTB19 legyen GPIO (MUX = 1)
PTB->PDDR |= 0x80000; // PTB19 legyen kimenet (bit19=1)
PTB->PSOR = 0x80000; // Zöld LED lekapcsolása (negatív logika!)
PORTD->PCR[1] = 0x100; // PTD1 legyen GPIO (MUX = 1)
PTD->PDDR |= 0x02; // PTD1 legyen GPIO (MUX = 1)
PTD->PSOR = 0x02; // Kék LED lekapcsolása (negatív logika!)
}
Sikeres programletöltés után kapcsolódjunk a kártyához a választott terminál emulátor programmal, majd a kártya RESET gombjának megnyomásával indítsuk el a programot! Az ABC betűin, vagy a számjegyeken végigzongorázva váltogathatjuk a z RGB színek kombinációit a LED-en.

Az UART2 port használata USB-UART átalakítóval

A következő két példaprogramban az UART2 portot fogjuk használni, s a PTE22 (Tx), PTE23 (Rx) kivezetéseken keresztül csatlakozunk hozzá. Az MKL25Z128VLK4 mikrovezérlőt azért látták el több UART porttal, hogy olyan eszközökkel tudjon egyidejűleg kommunikálni, amelyek ilyen csatoló felülettel vannak ellátva (pl. GPS vevő, WiFi modul, másik mikrovezérlő, vagy vonalmeghajtóban illesztett LIN, esetleg MODBUS eszköz). Ebben a bevezető tananyagban természtesen nem akarunk belebonyolódni ilyen komplex projektekben, csupán arra vállalkozunk, hogy az UART2 port kezelését bemutassuk. Ezért a kommunikáció megvalósításához egy USB-UART átalakítót használunk, melyet a számítógéphez csatlakoztatunk, s az előzőekhez hasonlóan, egy terminál emulátor programmal ellenőrizzük a működést.


7. ábra: FT232 USB-UART átalakító
A kapcsolat létrehozásához egy olyan USB-UART átalakítóra lesz szükségünk, amely nem RS-232 jelszinteket, hanem 3,3 V-os logikai jelet ad ki és fogad a Tx/Rx kivezetésein. A fenti ábrán látható FT232 alapú illesztő modul átkötéssel konfigurálható 5 V-os vagy 3,3 V-os jelszinthez. Nekünk a FRDM-KL25Z kártyához természetesen a 3,3 V-os jelszintet kell választanunk. Az összekötéshez csatlakoztassuk a modul Rx kivezetését a FRDM-KL25Z kártya PTE22 kivezetéséhez, a modul Tx kivezetését a FRDM-KL25Z kártya PTE23 kivezetéséhez, és kössük össze a két kártya GND kivezetéseit!


8. ábra: Az FT232 modul bekötése UART2 használatához


Program4_3: Egyszerű kiíratás az UART2 soros porton

"Hello" szöveget küldünk folyamatosan a FRDM-KL25Z kártya UART2 Tx (PTE22) kimenetén keresztül. Használjunk egy 3,3 V jelszintű USB-soros átalakítót az üzenetek PC-re küldéséhez és valamilyen terminál emulátor programot (PUTTy.exe,  Termite, TeraTerm stb.) az üzenetek megjelenítéséhez, az alábbi beállítással:  9600 bps, 8N1, adatfolyam vezérlés nélkül. Az UART2 vevő modulját most nem használjuk, így konfiguráláskor nem is engedélyezzük.
 
Az UART1 és UART2 modul mindig a rendszerbusz órajelét használja, amelyet a SystemInit() függvény alapértelmezetten a 20.97 MHz FLL CPU órajel frekvenciájának felére, azaz 10.49 MHz-re  állít be. Ennek megfelelően az előző programokban használt SBR értéket is felezni kell! A túlmintavételezési arány nem állítható (mindig 16-szoros). A programban használt BDH=0, BDL=0x44 beállításokkal tehát ugyanúgy 9600 Baud körüli lesz a sebesség, mint az előző programoknál.

Megjegyzés: Ha az RTE futtatói környezet system_MKL25Z4.h állományában nulla értékkel definiáljuk a CLOCK_SETUP makrót, akkor mind a CPU, mins a rendszerbusz frekvenciája 20.97152 MHz lesz, tehát az explicit módon megadott MCG 0 mód és az alapértelmezett beállítás különböznek! A CLOCK_SETUP makró definiálásához a system_MKL25Z4.h állományba szúrjuk be az alábbi sort:
#define CLOCK_SETUP 0  // Előre definiált beállítás: CPU és busz órajel = 20.97152 MHz
A fenti sor beszúrása után a buszfrekvencia az alapértelmezett érték duplája lesz, tehát BDH=0, BDL=0x88
beállításokkal kapunk 9600 bps adatátviteli sebességet. Mi az alábbi programnál nem definiáltuk a CLOCK_SETUP makrót, ezért az alapértelmezett (kisebb) buszfrekvenciához való BDH=0, BDL=0x44 beállítást használjuk. 

Az UART2 soros portot az MKL25Z128VLK4 mikrovezérlő a PTE22 (Tx) és PTE23 (Rx) lábain keresztül kötjük az USB-UART átalaítóhoz, ezért az adatküldéshez az UART0 port beállítása mellett a PTE22 kivezetést kell konfigurálnunk.

A konfigurálás lépései nagyon hasonlóak az előzőekhez, de az UART1 és UART2 modulok esetén két lépést "megspórolunk", mivel nem kell beállítani az UART órajel forrását (az mindig a rendszerbusz órajele lesz) és nem kell megadni a túlmintavételezési arányt sem (az mindig 16-szoros lesz)

A konfigurálás lépései:
  1. Engedélyezzük az UART2 modult a SIM_SCGC4 regiszter 12. bitjének 1-be állításával.
  2. Az UART2 Tx/Rx letiltása konfigurálás előtt: UART2_C2 regiszter TE=0, RE = 0.
  3. Az UART2 bitsebesség konfigurálása UART2_BDH és UART2_BDL beírásával.
  4. Adatformátum konfigurálása: 1 stop bit, nincs paritás vizsgálat, 8-bites adat megadásához írjunk 0x00-t  az UART2_C1 vezérlő regiszterbe!
  5. Engedélyezzük UART2 adóját:  írjunk 0x08-at az UART2_C2 regiszterbe (TE bit = 1)!
  6. Engedélyezzük az E portot: a SIM_SCGC5 regiszter 13. bitje legyen 1!
  7. Válasszuk ki a PTE22 kivezetés Alt4 funkcióját (UART2_Tx) PORTE_PCR22 MUX=4.

Az adatküldés lépései:
  1. Vizsgáljuk a Status Register 1 (UART2_S1) TDRE bitjét és várjunk addig, amíg a küldő buffer üressé válik (TDRE = 1)!
  2. Írjuk bele a kiküldendő bájtot az UART2_D adatregiszterbe!
  3. Újabb karakter kiküldéséhez menjünk a 8. ponthoz!
 
3. lista: Program4_3/main.c listája
/* Program4_3
*
* "Hello" szöveget küldünk folyamatosan a FRDM-KL25Z
* kártya UART2 Tx kimenetén keresztül. Használjunk egy
* USB-soros átalakítót és valamilyen terminál emulátor
* programot az üzenetek megjelenítéséhez!
* Beállítások: 9600 bps, 8N1, adatfolyam vezérlés nélkül.
*
* A program forrása: Mazidi et al., Freescale ARM Cortex-M Embedded Programming
* http://www.microdigitaled.com/ARM/Freescale_ARM/Code/Ver1/Chapter4/Program4_3.txt
*/

#include <MKL25Z4.h>

void UART2_init(void); // UART2 kimenet inicializálása
void delayMs(int n); // Késlelteto függvény

int main (void) {
char message[] = "Hello\r\n"; // Ez lesz a kiírandó szöveg
int i; // Ciklusváltozó
UART2_init();
while (1) {
for (i = 0; i < 7; i++) {
while(!(UART2->S1 & 0x80)); // Várunk, míg üres lesz a kimeneti buffer!
UART2->D = message[i]; // Következo karakter küldése
}
delayMs(2000); // Várunk egy kicsit...
}
}

/* UART2 Tx (PTE22) inicializálása 9600 Baud átviteli sebességre
* Baudrate = bus freq / 16 / BDH:BDL
* Esetünkben 10.49 MHz / 16 / 0x00:0x44 = 9637 bps
* Megjegyzés: UART2 órajele a buszfrekvencia, túlmintavételezés aránya mindig 16
*/
void UART2_init(void) {
SIM->SCGC4 |= 0x1000; // UART2 periféria engedélyezése
UART2->C2 = 0; // UART2 letiltása a konfigurálás idotartamára
UART2->BDH = 0x00; // Baudrate = 9600 bps (bit8 - bit12)
UART2->BDL = 0x44; // Baudrate = 9600 bps (bit0 - bit7)
UART2->C1 = 0x00; // 8-bites adatformátum
UART2->C3 = 0x00; // Nincs hibainterrupt
UART2->C2 = 0x08; // Adatküldés engedélyezése

SIM->SCGC5 |= 0x2000; // PORTE engedélyezése (bit 13)
PORTE->PCR[22] = 0x0400; // PTE22 legyen UART2_Tx üzemmódban (Alt4)
}

/* Késleltető függvény: Várakozás n milliszekundumig
* A CPU rendszerórajel alapértelmezett értéke 20.97152 MHz
*/
void delayMs(int n) {
int i;
int j;
for(i = 0 ; i < n; i++)
for (j = 0; j < 3500; j++) {}
}
Apró és lényegtelen különbség, hogy itt a kiíratást egy tömbből, for programciklus segítségével végezzük. Több karakter kiírása esetén nyilván ez a célszerűbb megoldás. A kiírt szöveg végén egy CR+LF (kocsi-vissza és soremelés) sorvége jelzést is küldünk , így minden kiratás új sorba kerül.  A C nyelvű programokban az \r jelenti a kocsi-vissza (0x0D), az \n pedig a soremelés (0x0A) karaktert.

Program4_4: Karakter visszatükrözés az UART2 soros porton

Ez a program egy karaktert fogad az UART2 port bemenetén  majd a karakter kódját eggyel megnövelve visszaírja az UART2 port kimenetére. Használjunk egy 3,3 V jelszintű USB-soros átalakítót az üzenetek PC-re küldéséhez és valamilyen terminál emulátor programot (PUTTy.exe,  Termite, TeraTerm stb.) az üzenetek megjelenítéséhez, az alábbi beállítással:  9600 bps, 8N1, adatfolyam vezérlés nélkül.
 
Az UART2 soros portot az MKL25Z128VLK4 mikrovezérlő a PTE22 (Tx) és PTE23 (Rx) lábain keresztül kötjük az USB-UART átalaítóhoz, ezért az adatküldéshez az UART0 port beállítása mellett ezeket a kivezetéseket is konfigurálnunk kell.

A konfigurálás lépései:
  1. Engedélyezzük az UART2 modult a SIM_SCGC4 regiszter 12. bitjének 1-be állításával.
  2. Az UART2 Tx/Rx letiltása konfigurálás előtt: UART2_C2 regiszter TE=0, RE = 0.
  3. Az UART2 bitsebesség konfigurálása UART2_BDH és UART2_BDL beírásával.
  4. Adatformátum konfigurálása: 1 stop bit, nincs paritás vizsgálat, 8-bites adat megadásához írjunk 0x00-t  az UART2_C1 vezérlő regiszterbe!
  5. Engedélyezzük UART2 adóját és vevőjét:  írjunk 0x0C-t az UART2_C2 regiszterbe (TE bit = 1, RE bit =1)!
  6. Engedélyezzük az E portot: a SIM_SCGC5 regiszter 13. bitje legyen 1!
  7. Válasszuk ki a PTE22 kivezetés Alt4 funkcióját (UART2_Tx) PORTE_PCR22 MUX=4.
  8. Válasszuk ki a PTE23 kivezetés Alt4 funkcióját (UART2_Rx) PORTE_PCR23 MUX=4.

Az adatfogadás és küldés lépései:
  1. Vizsgáljuk a Status Register 1 (UART2_S1) RDRF bitjét és várjunk addig, amíg egy karakter érkezik a bufferbe (amíg RDRF = 1 nem lesz)!
  2. Olvasuk ki a vett karaktert az UART0_D adatregiszterből!
  3. Vizsgáljuk a Status Register 1 (UART2_S1) TDRE bitjét és várjunk addig, amíg a küldő buffer üressé válik (TDRE = 1)!
  4. Írjuk bele a beolvasott karakter eggyel megnövelt kódját az UART2_D adatregiszterbe!
  5. Újabb karakter kiküldéséhez menjünk a 9. ponthoz!
 
Megjegyzés: Mi az alábbi programnál nem definiáltuk a CLOCK_SETUP makrót, ezért az alapértelmezett (10,49 MHz) buszfrekvenciához való BDH=0, BDL=0x44 beállítást használjuk. Ha az RTE futtatói környezet system_MKL25Z4.h állományában nulla értékkel definiáljuk a CLOCK_SETUP makrót, akkor viszont a BDL=0x44 értéket meg kell duplázni: BDL = 0x88 kell helyette, az azonos adatsebesség beállításához!  


4. lista: Program4_4/main.c listája
/* Program4_4 Uart echo
*
* Ez a program egy karaktert fogad az UART2 port bemenetén
* majd eggyel megnövelve visszaírja az UART2 port kimenetére.
* Használjunk egy USB-soros átalakítót a kapcsolódáshoz
* és valamilyen terminál emulátor programot az üzenetek megjelenítéséhez!
* Beállítás: 9600 bps, 8N1, adatfolyam vezérlés nélkül.
*
* A program forrása: Mazidi et al., Freescale ARM Cortex-M Embedded Programming
* http://www.microdigitaled.com/ARM/Freescale_ARM/Code/Ver1/Chapter4/Program4_1.txt
* Változtatások (Cserny I.):
* - Baudrate újraszámolása az eltéro busz orajel frekvencia miatt
* - Kivezetések átkonfigurálása PTE22, PTE23-ra
* - A visszatükrözött karakter kódját eggyel megnöveljuk
*/

#include <MKL25Z4.h>

void UART2_init(void); // UART2 kimenet inicializálása

int main (void) {
char c;
UART2_init();
while (1) {
while(!(UART2->S1 & 0x20)); // Karakter beérkezésre várunk
c = UART2->D ; // Beolvassuk a vett karaktert
while(!(UART2->S1 & 0x80)); // Várunk míg kiürül a küldo buffer
UART2->D = c+1; // Kiküldjük az eggyel megnövelt kódot
}
}

/* UART2 Tx (PTE22) inicializálása 9600 Baud átviteli sebességre
* Baudrate = bus freq / 16 / BDH:BDL
* Esetünkben 10.49 MHz / 16 / 0x00:0x44 = 9637 bps
*/
void UART2_init(void) {
SIM->SCGC4 |= 0x1000; // UART2 periféria engedélyezése
UART2->C2 = 0; // UART2 letiltása a konfigurálás idotartamára
UART2->BDH = 0x00; // Baudrate = 9600 bps (bit8 - bit12)
UART2->BDL = 0x44; // Baudrate = 9600 bps (bit0 - bit7)
UART2->C1 = 0x00; // 8-bites adatformátum
UART2->C3 = 0x00; // Nincs hibainterrupt
UART2->C2 = 0x0C; // Adatküldés és fogadás engedélyezése

SIM->SCGC5 |= 0x2000; // PORTE engedélyezése (bit 13)
PORTE->PCR[22] = 0x0400; // PTE22 legyen UART2_Tx üzemmódban (Alt4)
PORTE->PCR[23] = 0x0400; // PTE23 legyen UART2_Rx üzemmódban (Alt4)
}

Uart_retarget: A stdio átirányítása az UART0 soros portra

Joseph Yiu: „The Definitive Guide to ARM® Cortex®-M0 and Cortex-M0+ Processors” c. könyvének egyik mintapéldája (18_2_uart_retarget) alapján bemutatjuk, hogy a printf() és a scanf() függvények számára hogyan irányíthatjuk át az UART0 portra a stdio ki- és bemenetet. Az eredeti programot némileg leegyszerűsítettük (kiszedve belőle a LED vezérlést) és a kimenetet is átalakítottuk: egyszerű visszatükrözés helyett kiíratjuk a vett karakter betűképét és ANSI kódját is.

A stdio átirányítására általában két lehetőség kínálkozik:
Az első módszerhez a Keil MDK5 esetén a fputc(), fgetc() és ferror() függvényeket kell felüldefiniálni. A szükséges kódrészeket a mintaprojekt retarget.c állomány tartalmazza.

Az UART0 kezeléséhez szükséges függvényeket (UART_config(), UART_putc(), UART_getc(), UART_echo(), UART_puts()) az uart_funcs.c állomány tartalmazza. Ezek ismertetésére itt nem térünk ki részletesen, hiszen  ezek a függvények is lekérdezéssel, a fentebb bemutatott programokhasonlóan működik. Amire ki kell térnünk, az a konfigurálás, amit ebben a programban egy kicsit másképp csinálunk, mint korábban:

1. A mikrovezérlő órajelét most a külső kvarcot használó oszcillátor és a PLL áramkör segítségével állítjuk elő. Ez system_MKL25Z4.h állományban előre definiált rendszerórajel konfigurációk közül az 1. sorszámú beállítást jelenti. Ekkor a CPU órajele 48 MHz lesz (külső kvarccal), a buszfrekvencia pedig 24 MHz lesz. Ennek kiválasztásához új projekt létrehozásakor, a projekt lefordítása előtt a system_MKL25Z4.h állományba be kell szúrnunk az alábbi sort:
#define CLOCK_SETUP 1
2. Ahhoz, hogy az UART0 órajel forrása az így beállított 48 MHz CPU frekvencia legyen, a SIM_SOPT2 regsizter bit27-26 = 01 és bit 16 = 1 legyen!

3. Lényegtelen különbség, hogy ebben a programban nem 16x-os túlmintevételezés van beállítva, hanem 4x-es túlmintavételezési arány, mindkét élen történő mintavételezéssel.

A projekthez csatolt retarget.c állománynak köszönhetően felüldefiniálásra kerülnek a fputc(), fgetc() és ferror() függvények. Ez azt jelenti, hogy a  főprogramban az UART_config() meghívása után  a kiíratásokhoz használhatjuk a printf(), a beolvasásokhoz pedig a scanf() függvényt.

A program induláskor kiír egy üdvözlő üzenetet, majd egy név beírására vár. A beírást szóköz karakter begépelésével lehet lezárni. Ezután a program visszatükrözi a beírt nevet, majd elkezdődik a végtelen ciklus. A ciklusban minden karakterre visszaírjuk a karaktert, majd a karakter ANSI kódját is.

Megjegyzések:
5. lista: Uart_retarget/main.c listája
#include <MKL25Z4.H>
#include "stdio.h"
// System runs at 48MHz
// Baud rate 38400, 8 bit data, no parity, 1 stop bit

// UART functions
extern void UART_config(void);
extern char UART_putc(char ch);
extern char UART_getc(void);
extern void UART_echo(void);
extern void UART_puts(char * mytext);


int main(void) {
char txt_buf[100];
char c;
SystemCoreClockUpdate();
UART_config();
printf("\r\nWelcome to FRDM-KL25Z board!\r\n");
printf("Please enter your name:");
scanf("%99s", txt_buf);
printf("\nName entered :[%s]\n", txt_buf);
while(1){
c = UART_getc(); //Read one character
printf("received char: %c = %d\r\n",c,c);
}
}


9. ábra: Az Uart_retarget program futási eredménye
 

Felhasznált anyagok és ajánlott olvasmányok: