9.1.1. ARM mikrovezérlők programozása E fejezetben az ARM mikrovezérlők programozása lesz ismertetve néhány példaprogram és gyakorlati alkalmazás bemutatásával. Az általunk használt ARM mikrovezérlő gyártója (Texas Instruments) sok példaprogrammal és dokumentációval segíti a programozók munkáját. Ezekben a segédletekben részletesen kidolgozott programokkal és magyarázatokkal találkozunk a mikrovezérlő moduljai, és a fejlesztőeszközök használatáról. Ezeket átnézve és a gyakorlatba átültetve könnyen és gyorsan megismerkedhetünk a beágyazott eszközök programozásával.A bemutatásra kerülő példaprogramok eléréséhez telepíteni kell a Stellaris Ware programocsomagot (http://www.ti.com/tool/sw-lm3s), a programok fordítására, mikrovezérlő programozására és debuggolására az ingyenes Code Composer Studio programocsomagot használjuk (http://www.ti.com/tool/ccstudio#buy).
ARM Cortex-M3 GPIO programozása HPLC-n keresztül Az eslő példaprogram a már korábban bemutatott, általunk fejlesztett HPLC egy gyakorlati alkalmazását fogja bemutatni. A HPLC használható különböző fogyasztók mint például világítótestek előre programozott vagy feltételtől függő ki-be kapcsolására. Ezt a műveletet relé segítségével végzi, amely alkalmas e nagyobb teljesítményű fogyasztók kapcsolására. A relé kapcsolásához szükséges tekercs gerjesztését viszont a mikrovezérlő nem tudja ellátni, ezért a tekercs táplálását egy tranzisztor segítségével végzi, ahogyan az a következő kapcsolási rajzon is látszik.
A program a mikrovezérlő azt a GPIO lábát konfigurálja kimenetnek, mellyel a relé van vezérelve, és ezt a kimenetet másodpercenként ki/be kapcsolja. A program csak azokat a legfontosabb elemeket tartalmazza amik feltétlenül szükségesek a mikrovezérlő GPIO lábának konfigurálásához, és használatához. A programban használt függvények a meghajtó könyvtárban (Pheripherial Driver Library) találhatóak. A függvények részletes dokumentációja pedig a StellarisWare\docs\SW-DRL-UG8555.pdfdokumantumban található. A program indulásakor először a mikrovezérlő órajelét konfigurálja 50MHz-re. Ahogyan a kapcsolási rajzon (mellékelve a példaprogramhoz)is látszik, a mikrovezérlő órajelét egy 8MHzes kvarc oszcillátor szolgáltatja, ezt a mikrovezérlő belső PPL áramköre 200MHz-re szorozza, majd leosztja 4-el hogy 50MHz-et kapjunk. Ennek a mikrovezérlőnek ez a megengedett maximális működési frekvenciája. A programrészlet végzi el ezt a feladatot: SysCtlClockSet(SYSCTL_SYSDIV_4|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_8MHZ);
A kapcsolási rajzon látszik hogy a 0. relét a mikrovezérlő PB0-ás lába vezérli, azaz a Port B 0. lába. Hogy kimenetként használhassuk, először be kell kapcsolni a Port B perifériát, majd a 0. lábat kimenetnek konfigurálni. Ezt a következő programrész végzi: SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_0);
Az inicializálás után a program egy végtelen while ciklusba kerül ahol másodpercenként magas majd alacsony szintre állítja a kimenetet, ami a relét ki és be kapcsolja. while(1) { SysCtlDelay(16666666); GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_0, GPIO_PIN_0); SysCtlDelay(16666666); GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_0, 0); }
A kimenet állapotának beállítására a GPIOPinWritefüggvény szolgál. Paraméterként meg kell adni a láb portjának azonosítóját, és beállítani kívánt láb sorszámát, majd hogy alacsony vagy magas szintre akarjuk beállítani.A kapcsolások között eltelt időt a mikrovezérlő várakozással tölti, melyre a SysCtlDelay fűggvény szolgál. Ez a függvény a paraméternek megkapott szám háromszorosának megfelelő órajelnyi időt várakozik. ARM Cortex-M3 összetettebb perifériáinak programozása Az ARM Cortex M3-as mikrovezérlő család összetettebb perifériáinak használata és programozása, egy már előzőleg bemutatott fejlesztőeszközön lesz ismertetve. A példaprogramok eléréséhez előzőleg telepíteni kell e Stellaris Ware programcsomagot. Az alkalmazottfejlesztőeszköz azEKS-LM3S3748 amellyel az UART modul, grafikus LCD kijelző, használatát fogjuk bemutatni a StellarisWare programcsomagban található gyári példaprogramok segítségével. Az említett fejlesztőeszközhöz tartozó összes példaprogram megtalálható a következő elérési útvonalon: StellarisWare\boards\ek-lm3s3748\. Az EKS-LM3S3748 fejlesztőeszközön LM3S3748-as mikrovezérlő található (bővebb információk: http://www.ti.com/product/LM3S3748), amely 50MHz órajel sebességen működik. A mikrovezérlő összes GPIO (General Purpose Input-Output) lába ki van vezetve tűsorokra, melyekre szabadon csatlakoztathatunk bármilyen külső perifériát. A programozáshoz és debuggoláshoz szükséges kontroller az eszközre letervezve, tehát nem kell külön programozó egység a mikrovezérlő programozásához és debuggolásához. Ehhez a számítógéptől érkező mini USB csatlakozót a DEBUG USB csatlakozóba kell helyezni. A fejlesztőeszköz két helyről kaphat táplálást, vagy külső 5V-os tápforrástól, vagy a számítógép USB tápfeszültségétől. A tápforrást kiválasztó kapcsoló SELF állásában a külső 5V-os tápról, vagy az USB busz tápforrásáról kapja, az USB buszról csak abban az esetben ha az USB kábel a DEBUG USB csatlakozóba van helyezve. A kapcsoló BUS álatpotában az USB busz tápforrását használja, ekkor az USB vezetéket az USB DEVICE csatlakozóba kell helyezni. UART modulhasználatát bemutató példaprogram (uart_echo) Az első példaprogram az UART modul használatát mutatja be. A fejlesztőeszközön található programozáshoz és debuggoláshoz szükséges kontroller, két virtuális COM portként jelenik meg
PC oldalon. E két COM portból az egyik össze van kötve a mikrovezérlő UART_0 moduljával, tehát használható PC-vel való kommunikálásra. A virtuális COM port PC oldalról nézve olyan mintha a számítógép RS-232 portjával kommunikálna, viszont a fejlesztőeszköz USB kábellel van összekötve a PC-vel. A példaprogram egy egyszerű ’echo’ műveletet hajt végre, amely az UART modulnak érkező ascii karaktereket ugyanolyan formában visszaküldi. A program fordítására, mikrovezérlő programozására és debuggolására, a már előzőleg bemutatott Code Composer Studio fejlesztőkörnyezetet használjuk. A program törzse, és a main függvény az uart_echo.c fájlban található. A program használja a meghajtó könyvtárat (Pheripherial Driver Library), és az LCD kijelzőhöz tartozó grafikus könyvtárat (Graphics Library). Induláskor az első művelet a mikrovezérlő órajelének beállítása. Mivel az UART modul aszinkron kommunikációs protkoll, ez azt jelenti, hogy az átviteli közegen az órajel nem kerül átvitelre. Ebben az esetben mindkét kommunikáló fél a saját órajeléhez szinkronizálja a kommunikációt, ehhez pedig pontosan ismert és stabil órajelre van szükség. Az instabil órajel kommunikációs hibákhoz vezethet. Az órajel beállításához tudni kell a mikrovezérlő órajelét szolgáltató áramkör (oszcillátor, órajel generátor) frekvenciáját, a mi esetünkben 8MHz. A mikrovezérlő használhatja ezt az órajelet, vagy nagyobb sebesség eléréséhez a mikrovezérlőn belül egy PLL (Phase Locked Loop) áramkörrel megnövelheti azt. A mikrovezérő belső PLL áramkörének használata esetén 200MHz-re szorzódik az órajel, amit le kell osztani, úgy hogy a kapott frekvencia ne haladja meg a mikrovezérlő maximális működési frekvenciáját (LM3S3748 esetén 50MHz). A mikrovezérlő órajelének beállítását a következő könyvtári függvény végzi: ROM_SysCtlClockSet(SYSCTL_SYSDIV_1|SYSCTL_USE_OSC|SYSCTL_OSC_MAIN|SYSCTL_XTAL_8MHZ);
A továbbiakban az LCD kijelző konfigurálásra történik (melyről bővebben a következő példánál olvashatunk), majd kiíratásra kerülnek az UART modul beállításai. Formike128x128x16Init(); Formike128x128x16BacklightOn(); GrContextInit(&g_sContext, &g_sFormike128x128x16);
// Initialize the display driver. // Turn on the backlight. // Initialize the graphics context.
A kijelzőre kiirt paraméterek szerint kell a Virtuális COM porthoz csatlakoni. Az UART modul beállításához először az UART perifériát (UART0), és azt a portot kell aktiválni amelyet az UART modul két kommunikációs vonala (TXD, RXD) használ (GPIOA). ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
Ezután következik az UART modul lábainak hozzárendelése a megfelelő porthoz majd maga a modul konfigurálása a következő paraméterekkel: Baud rate = 115200, Data bits = 8, Parity = none, Stop bit = 1. ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); ROM_UARTConfigSetExpClk(UART0_BASE, ROM_SysCtlClockGet(), 115200 (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
A megszakítás vezérlőt úgy kell beállítani, hogy megszakítást generáljon, ha egy új karakter érkezett az UART modulnak. Az UART megszakítás engedélyezését, és a megszakításvezérlő beállítását a következő kódrészlet végzi: ROM_IntEnable(INT_UART0); ROM_UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);
A szükséges modulok, és perifériák konfigurálása után a program egy üres végtelen while ciklusban marad, ahonnan csak az UART modultól érkező megszakítás elvégzésére lép ki. Ugyanis ha a PC-tól érkezik egy karakter, az egy megszakítást generál, és a beérkezett karakter kiolvasását és visszaküldését a megszakítást kiszolgáló függvény végzi. A megszakításkezelő függvény (void UARTIntHandler(void)) a ROM_UARTCharGetNonBlocking könyvtári függvény segítségével olvassa ki a beérkezett karaktert, a karaktert, mint visszatérési érték adja vissza a ROM_UARTCharPutNonBlocking függvénynek, ami visszaküldi a fogadott karaktert a PC-nek. Ez a ködrészlet látható az alábbiakban: ROM_UARTCharPutNonBlocking(UART0_BASE,ROM_UARTCharGetNonBlocking(UART0_BASE));
A projekt (StellarisWare\boards\ek-lm3s3748\uart_echo) megnyitása, fordítása, és mikrovezérlőbe történő betöltése után a következőket kell még megtennünk hogy eredményt láthassunk: A fejlesztőlap csatlakoztatásakor az Windows Eszközkezelő ablakában megjelenik két virtuális COM port (Stellaris Virtual COM Port), a kettő közül az egyik az, amelyiken keresztül kommunikálhatunk a mikrovezérlővel (hogy melyik az, azt legegyszerübb probálkozással kideríteni). Amennyiben csak egy virtuális COM port jelenik meg, akkor az Eszközkezelő, ‘Universal Serial Bus’ controllers lenyíló menüben a ’Stellaris Evaulation Board A’ beállítása között a ’Load VCP’ jelölő négyzetet be kell jelölni, és újracsatlakoztatni a fejlesztőeszközt. Ezután szükségünk lesz egy Terminál programra, ami segítségével kommunikálhatunk a számítógép COM portjával (pl. Real Term,melyet a következő oldalrol lehet lehet ingyenesesn letölteni http://realterm.sourceforge.net/). A programban a megfelelő COM port kiválasztása után csatlakozzunk hozzá. A fejleszőeszköz újraindítása után az “Enter text:” szöveg fog megjelenni a terminál program képernyőjén. Ezután az fejlesztőeszköznek küldött minden karakter visszaküldésre kerül, esetünkben a “Hello World!”
A COM porttal kommunikáló terminál program
A grafikus LCDhasználatát bemutató példaprogram (grlib_demo) A fejlesztőeszközön található 128x128 pixel felbontású LCD kijelző használatának legegyszerűbb módja, ha a Stellaris Ware szoftvercsomagban található Grafikus Könyvrár függvényeit használjuk. A bemutatásra kerülő példaprogram e könyvtár használatát reprezentálja. A könyvtári függvények használatához egy meghajtó függvénycsomag szükséges, melyen keresztül a grafikus könyvtár függvényei elérhetik az LCD kijelző alapvető funkcióit. Ilyen funkciók a parancsküldés, pixel rajzolása, vonal rajzolása, háttérvilágítás ki-bekapcsolása. A fejlesztőeszközön levő LCD kijelzőhöz természetesen mellékelték a megfelelő meghajtó függvényeket is, amelyek a StellarisWare\boards\ek-lm3s3748\drivers\formike128x128x16.c fájlban találhatóak. A grafikus könyvtár függvényei bármilyen kijelzővel használhatóak, csak a megfelelő meghajtó függvényeket kell megírni hozzá. A könyvtár használatához szükséges segédlet a StellarisWare\docs\SW-GRL-UG-8555.pdf dokumentumban található. Az előző példához hasonlóan, ennél is először a mikrovezérlő órajele majd a perifériák inicializálása történik. Az LCD kijelző inicializálása a grafikus könyvtár függvényei segítségével történik. A Formike128x128x16Init();függvény végzi a mikrovezérlő azon portjainak és moduljainak inicializálását, melyeket az LCD-vel való kommunikálásra használ, majd a megfelelő parancsok elküldésével egy kezdeti inicializált állapotba hozza a kijelzőt. A kijelző, és a kijelzőn megjelenő kép fontosabb paramétereit, mint például a kijelző felbontása, a megjelenített kép háttér színe, előtér színe, a használt betűtipus és méret, stb a tContext g_sContextstruktúra csoportosítja. A példaprogramban ez mint globális változó van deklarálva. Ezt a struktúrát mint paramétert minden olyan függvény használja, amely valamilyen modifikációt végez az LCD kijelzőre kirajzolt képen (karakter kiírása, vonalak, körök, kép kirajzolása, stb). A tContext g_sContext struktúrát a GrContextInit(&g_sContext, &g_sFormike128x128x16);függvény inicializálja, melynek át kell adni magát az inicializálni kívánt struktúrát, és a g_sFormike128x128x16struktúrát amely a kijelző méretét, és a meghajtófüggvények mutatóit tartalmazzák. A példaprogram a következő rajzelemek alkalmazását ismerteti: üres és színezett téglalap, üres és színezett kör, horizontális és vertikális vonalak, kép, és szöveg kirajzolása a kijelzőre. A program betöltése és futtatása után a következő képen levő eredményt kell látnunk.
A grafikus könyvtárat bemutató példaprogram szemléltetése