UNIVERZITA TOMÁŠE BATI VE ZLÍNĚ FAKULTA APLIKOVANÉ INFORMATIKY
PROGRAMOVÁNÍ MIKROPOČÍTAČŮ CVIČENÍ 5 Práce s přerušením, zpracování stisku tlačítka Jan Dolinay Petr Dostálek Zlín 2013
Tento studijní materiál vznikl za finanční podpory Evropského sociálního fondu (ESF) a rozpočtu České republiky v rámci řešení projektu: CZ.1.07/2.2.00/15.0463, MODERNIZACE VÝUKOVÝCH
MATERIÁLŮ A DIDAKTICKÝCH METOD
Cvičení 5 – Práce s přerušením, zpracování stisku tlačítka
Cvičení 5 – Práce s přerušením, zpracování stisku tlačítka
STRUČNÝ OBSAH CVIČENÍ:
Princip přerušení Ukázkový program – blikání LED řízeno tlačítkem Úkoly k procvičení
VSTUPNÍ ZNALOSTI: Toto cvičení předpokládá znalosti z předchozích cvičení a z přednášky zabývající se přerušením.
CÍL:
Na tomto cvičení si ukážeme, jak lze v programech využít přerušení. Cílem cvičení je naučit se využívat přerušení a to konkrétně přerušení vzniklé při stisku tlačítka (změna logické úrovně na vstupu) a přerušení od časovače.
Cvičení se vztahuje k těmto otázkám
Přerušovací systém mikropočítače HC08 – princip obsluhy přerušení, typy přerušení
MODERNIZACE VÝUKOVÝCH MATERIÁLŮ A DIDAKTICKÝCH METOD CZ.1.07/2.2.00/15.0463,
2
Cvičení 5 – Práce s přerušením, zpracování stisku tlačítka
Řešené příklady Příklad 1 – Blikání LED ovládané tlačítkem, přerušení od klávesnice
Úkol: Vytvořte program, který bude blikat LED1 s periodou cca 2s (1s svítí a 1s nesvítí). Tlačítkem SW1 bude možno blikání zastavit a znovu spustit.
Řešení V tomto programu využijeme přerušení od klávesnice (modul KBI) pro detekci stisku tlačítka. Blikání LED budeme realizovat pomocný cyklu (smyčky) tak, že střídavě změníme stav bitu číslo 0 na portu F (kde je připojena LED1). Přitom mezi každým průchodem cyklem je prodleva asi 1 sekunda aby LED vždy cca 1 sekundu svítila a 1 sekundu pak nesvítila. Bez této prodlevy by bylo rozsvěcení a zhasínání tak rychlé, že by žádné blikání nebylo vidět. Využití přerušení zaručuje okamžitou reakci na stisk tlačítka i když se hlavní program právě nachází v čekací smyčce. Pro prodlevu použijeme podprogram cekej, který jsme viděli už dříve. Princip programu je znázorněn na následujících vývojových diagramech.
Obr. 1 – Vývojový diagram příkladu na obsluhu stisku tlačítka pomocí přerušení MODERNIZACE VÝUKOVÝCH MATERIÁLŮ A DIDAKTICKÝCH METOD CZ.1.07/2.2.00/15.0463,
3
Cvičení 5 – Práce s přerušením, zpracování stisku tlačítka
Na obrázku je nalevo (žlutě) vývojový diagram hlavního programu a napravo (zeleně) vývojový diagram pro podprogram, který je spuštěn, když dojde k přerušení – tj. obsluha přerušení. Celkově je program navržen tak, že v hlavním programu se v závislosti na hodnotě proměnné blikej buď neprovádí nic, nebo se rozvětvuje a zhasíná LED1. Proměnná blikej je měněna při stisku tlačítka v obsluze přerušení. V hlavním programu nejprve inicializujeme port F, kde jsou připojeny LED diody, tj. nastavíme příslušný vývod (pin) portu jako výstupní a vypneme pull-up rezistory. Podobně nakonfigurujeme příslušný vývod portu A (kde je připojeno tlačítko) jako vstupní a zapneme pull-up rezistor. Dále inicializujeme modul KBI tak, aby při změněně logické úrovně na tomto pinu bylo vyvoláno přerušení. Poté povolíme přerušení instrukcí CLI a do proměnné blikej nastavíme hodnotu 1, která znamená, že blikání je zapnuto. Po spuštění programu tedy bude LED blikat a prvním stiskem tlačítka SW1 se blikání vypne. Dalším stiskem pak zapne, dalším vypne atd.
Jak se vidět v dalším bloku vývojového diagramu hlavního programu (žlutý), testuje se pak hodnota proměnné blikej a jestliže není rovna jedné, program se vrací zpátky na test, tj. neprovedou se zbylé dva bloky, které zajišťují blikání LED, viz větev NE. Z toho plyne, že jestliže je blikej = 0, LED nebliká, jestliže je blikej = 1, LED bliká. Blikání je vytvořeno tak, že rozsvítíme LED a pozastavíme program na cca 1 sekundu. Potom LED zhasneme a opět program pozastavíme na 1 sec. Pak se vracíme zpět na začátek a vše se opakuje. LED tedy vždy 1s svítí a 1s nesvítí. Pokud někdo stiskne tlačítko, vyvolá se přerušení a provede se podprogram KBI_int, který je znázorněn vývojovým diagramem vpravo (zeleně). V tomto podprogramu se neguje nejnižší bit proměnné blikej. Tedy jestliže v ní byla hodnota 1, nastaví se nyní hodnota 0 (a LED nebude blikat). Jestliže naopak bude v proměnné blikej 0, nastaví se negací na 1 a LED začne opět blikat. Poté se čeká cca 10 ms na doznění zákmitů tlačítka a nakonec se vynuluje příznak probíhajícího přerušení zápisem do bitu KBACK v registru KBI1SC (viz popis registrů modulu KBI výše) a obsluha přerušení končí.
Použité instrukce a direktivy EOR – exkluzivní logický součet (XOR) mezi registrem A a paměťovou buňkou
MODERNIZACE VÝUKOVÝCH MATERIÁLŮ A DIDAKTICKÝCH METOD CZ.1.07/2.2.00/15.0463,
4
Cvičení 5 – Práce s přerušením, zpracování stisku tlačítka
Direktivy ORG – určení umístění kódu nebo dat v paměti mikropočítače. DC.W – viz obsluha přerušení, nasměrování.
Vysvětlení programu Zdrojový kód programu je rozdělen do čtyř částí, které jsou na výpisech na obr. 2 až 4. ; hlavní program MOV MOV MOV MOV MOV MOV CLI nav1
#$ff,PTFD #%00000001,PTFDD #0,PTFPE #%00000110,KBI1SC #%00010000,KBI1PE #1,blikej
; inicializace datoveho registru -> LED zhasnuty ; PTF0 vystupni rezim - zde je pripojena LED1 ; pull-up rezistory portu F deaktivovany ; povoleni preruseni od KBI, sestupna hrana vyvola preruseni ; PTA4 rezim KBI, ostatni rezim GPIO ; zapni blikani ; povol preruseni
LDA blikej feed_watchdog CMP #0 BEQ nav1 LDA PTFD AND #m_LED1_on STA PTFD JSR cekej LDA PTFD ORA #m_LED1_off STA PTFD JSR cekej BRA nav1
; A <- blikej
; pokud je blikej==0, neblikame
; rozsvit LED1 ; cekej 1s
; zhasni LED1 ; cekej 1s ; nekonecna smycka
Obr. 2 – kód hlavního programu
Na začátku pomocí instrukcí MOV provádíme inicializaci portu F (stejně jako v minulém příkladu, pro ovládání LED1 pomocí příslušného výstupu). Potom nastavujeme obvod pro generování přerušení KBI a to tak, aby přerušení vyvolala sestupná hrana na bitu 4 portu A (kde je připojeno tlačítko SW1). Srovnejte hodnoty použité u instrukcí MOV s významem odpovídajících bitů v registrech KBI1SC a KBI1PE na obrázcích v dokumentaci mikropočítače. Následuje test proměnné blikej. Jestliže je její hodnota rovna nule, vrací se program na návěští nav1 (skok BEQ) a nedostane se tedy do kódu, který ovládá blikání LED. MODERNIZACE VÝUKOVÝCH MATERIÁLŮ A DIDAKTICKÝCH METOD CZ.1.07/2.2.00/15.0463,
5
Cvičení 5 – Práce s přerušením, zpracování stisku tlačítka
Jestliže blikej není nulová, rozsvítí se LED1. To se provede třemi instrukcemi stejně jako v minulém příkladu: LDA PTFD AND #m_LED1_on STA PTFD Tedy nahraje se do reg. A obsah celého portu F, provede se logický součin (AND) s maskou, který zajistí, že bit kde je připojena LED1 se vynuluje (a tím se LED rozsvítí, viz minulá lekce), ale ostatní bity nebudou změněny. Výsledek AND je uložen do reg. A a my jej třetí instrukcí (STA PTFD) uložíme na port F a tím LED1 rozsvítíme. Následuje prodleva cca 1 sekunda zavoláním podprogramu cekej. Poté je LED1 zhasnuta pomocí tří instrukcí, opět jako v minulé lekci. Pak se opět cca 1s čeká zavoláním podprogramu cekej. Nakonec se program vrací zpět na návěští nav1 a testuje stav proměnné blikej. To vše se opakuje v nekonečné smyčce, viz instrukce nepodmíněného skoku BRA nav1. ; cekej – podprogram pro pozastaveni vykonavani programu na cca 1s cekej
n2 n1
PSHH PSHX PSHA LDA #18 LDHX #$FFFF AIX #-1 feed_watchdog CPHX #0 BNE n1 DECA BNE n2 PULA PULX PULH RTS
; uloz pouzivane registry na zasobnik
; H:X = H:X+1 (pozor, nenastavuje priznaky) ; reset watchdogu ; je H:X = 0? ; pokud ne, skoc na n1 ;A=A-1 ; je A=0? Pokud ne, skoc na n2
; obnov puvodni obsah registru ze zasobniku ; navrat z podprogramu
Obr. 3 – Kód podprogramu cekej
Na obr. 3 je podprogram cekej, který slouží k pozdržení běhu programu přibližně o 1 sekundu a to pomocí čekací smyčky. Takovýto způsob čekání není příliš elegantní, prozatím nám ale bude stačit. Později si vysvětlíme, jak lze pracovat s časem pomocí časovače. Podprogram cekej se skládá ze dvou vnořených smyček. Nejprve se do registru A nahrává číslo 18. Registr A zde slouží jako počitadlo pro vnější smyčku, takže vnitřní smyčka využívající registru H:X se provede osmnáctkrát. Kód vnitřní smyčky se pak opakuje tak dlouho, dokud je v registru H:X číslo větší než nula. Protože do H:X nahráváme číslo FFFF MODERNIZACE VÝUKOVÝCH MATERIÁLŮ A DIDAKTICKÝCH METOD CZ.1.07/2.2.00/15.0463,
6
Cvičení 5 – Práce s přerušením, zpracování stisku tlačítka
hexa tj. 65536 dekadicky, probíhá tato smyčka právě tolikrát. Uvnitř smyčky se nic užitečného neděje, pouze se resetuje watchdog a dekrementuje počitadlo. Tento podprogram vložíme v našem souboru až na konec zdrojového kódu, až za kód, který vygeneroval průvodce novou aplikací. Kód z následujících výpisů pak vkládáme také na konec, ještě za kód podprogramu cekej. ; cekej10ms – podprogram pro pozastaveni vykonavani programu na cca 10ms cekej10ms
n3
PSHH ; uloz pouzivane registry na zasobnik PSHX LDHX #$3000 AIX #-1 ; H:X = H:X-1 (pozor, nenastavuje priznaky) feed_watchdog ; reset watchdogu CPHX #0 ; je H:X = 0? BNE n3 ; pokud ne, skoc na n1 PULX PULH ; obnov puvodni obsah registru ze zasobniku RTS ; navrat z podprogramu
Obr. 4 – kód podprogramu cekej10ms
Na obr. 4 je podprogram pro čekání 10 ms, který se používá v obsluze přerušení. Princip je stejný jako u předchozího podprogramu cekej. Zde ovšem vystačíme s jednou smyčkou a do reg. H:X nahrajeme pouze číslo 3000 hexa. Provedení tohoto podprogramu pak trvá přibližně 10 ms, což je dostatečná doba abychom odfiltrovali případné zákmity tlačítka. Proč toto čekání vůbec používáme je vysvětleno níže v popisu kódu obsluhy přerušení. ; obsluha preruseni od KBI KBI_int
PSHH LDA EOR STA JSR BSET PULH RTI
; uloz registr H na zasobnik !!! blikej #%00000001 ; neguj 0.bit promenne blikej blikej cekej10ms ; pockej na ustaleni tlacitka 2,KBI1SC ; potvrzeni prijmu preruseni ; obnov registr H ze zasobniku !!! ; návrat z obsluhy preruseni
; nasmerovani vektoru preruseni KBI na nasi obsluhu ORG DC.W
$FFD2 KBI_int
; adresa vektoru preruseni od KBI ; vyplneni vektoru adresou nasi obsluhy
Obr. 5 – kód obsluhy přerušení MODERNIZACE VÝUKOVÝCH MATERIÁLŮ A DIDAKTICKÝCH METOD CZ.1.07/2.2.00/15.0463,
7
Cvičení 5 – Práce s přerušením, zpracování stisku tlačítka
Na obr. 5 je kód obsluhy přerušení. Tento kód je proveden, jestliže nastane přerušení od modulu KBI, tj. jestliže někdo stiskne tlačítko SW1. Nejprve se uloží na zásobník registr H, který není automaticky ukládám procesorem před provedením obsluhy přerušení (na rozdíl od ostatních registrů). Toto neuložení registru H je vlastnost procesorů HC08 zavedená z důvodů zpětné kompatibility. Pro správnou funkci programu by ovšem obsluha přerušení měla uchovat obsah všech pracovních registrů a tak je dobrým zvykem v každé obsluze přerušení na HC08 uložit na začátku obsah registru H na zásobník a na konci jej opět obnovit. Bit 0 proměnné blikej se invertuje pomocí operace XOR (exkluzivní logický součet). Tato logická operace s uvedenou maskou zajistí, že jestliže je nultý bit v proměnné blikej nastaven na 1, výsledek XOR s maskou bude 0 (nultý bit v masce je také 1 a XOR stejných operandů dá výsledek 0). Naopak, pokud bude v proměnné blikej nula, výsledek XOR s maskou bude 1. Nejnižší bit proměnné blikej je tedy při každém vykonání obsluhy přerušení invertován. Tím je zajištěno, že při opakovaných stiscích tlačítka se přepíná mezi stavem, kdy LED1 bliká a kdy nebliká. Čekání 10 ms (JSR cekej10ms) slouží k odfiltrování zákmitů tlačítka. Bez tohoto čekání by obsluha přerušení skončila příliš brzy a přerušení by mohlo být vyvoláno znovu ještě zákmitem od stejného stisku tlačítka, který už byl obsloužen. Obsluha přerušení je speciálním typem podprogramu a končí proto instrukcí RTI, nikoliv RTS jako běžný podprogram. Poslední část kódu, „nasměrování vektoru přerušení KBI na naši obsluhu“, zajišťuje uložení adresy naší obsluhy přerušení (kteoru jsme pojmenovlai KBI_int) na adresu vektoru přerušení KBI – tj. na adresu FFD2 hexa. K tomu je použita direktiva ORG, která definuje, na jakou adresu v paměti se má uložit kód za touto direktivou následující. Jinak řečeno, touto direktivou dáváme překladači příkaz, aby následující kód vložil do paměti mikropočítače na adresu, kterou zadáme. Obvykle tuto direktivu nepoužíváme a necháváme překladač aby kód i data našeho programu umístil do paměti podle libosti, protože toto umístění není pro nás důležité. V případě změny vektorů přerušení ale potřebujeme uložit adresu naší obsluhy na přesně danou adresu. Kód zapsaný za direktivou ORG bude tedy uložen do paměti mikropočítače od adresy $FFD2. A tímto kódem je adresa našeho podprogramu KBI_int, která je sem vložena direktivou DC.W (definuj konstantní word), viz popis použitých instrukcí a direktiv na začátku této lekce. Princip vektoru přerušení si můžeme objasnit takto: Náš podprogram KBI_int (který se má zavolat, když nastane přerušení po stisku tlačítka), je umístěn někde v paměti mikropočítače. Jak se procesor „dozví“, že až nastane příslušné přerušení, má provést právě naši obsluhu? (jinými slovy že má provést skok na podprogram KBI_int?). K tomu slouží tzv. vektory přerušení, což jsou určité předem definované místa (adresy) v paměti, ze kterých procesor MODERNIZACE VÝUKOVÝCH MATERIÁLŮ A DIDAKTICKÝCH METOD CZ.1.07/2.2.00/15.0463,
8
Cvičení 5 – Práce s přerušením, zpracování stisku tlačítka
zjišťuje adresy obsluh přerušení pro jednotlivé typy přerušení (např. od klávesnice, od časovače atd.). Pro přerušení od klávesnice je tato adresa $FFD2, což lze zjistit v dokumentaci k mikropočítači. Když nastane přerušení, procesor se „podívá“ na adresu, která odpovídá tomuto přerušení, a tam najde odkaz na podprogram, který se má vykonat. Jestliže tedy na adresu $FFD2 uložíme adresu našeho podprogramu, bude pak tento podprogram vykonán když nastane přerušení od klávesnice. Aby program mohl fungovat, musíme ještě definovat masky a proměnnou blikej: blikej m_LED1_on m_LED1_off
DS.B EQU EQU
1 %11111110 %00000001
Testování programu Před nahráním programu do vývojového kitu nezapomeňte provést restart do režimu monitoru, jako to bylo popsáno v minulé lekci, pomocí tlačítek SW4 a Reset. Program nekrokujte, nýbrž spusťte plnou rychlostí a vyzkoušejte jeho funkci.
MODERNIZACE VÝUKOVÝCH MATERIÁLŮ A DIDAKTICKÝCH METOD CZ.1.07/2.2.00/15.0463,
9
Cvičení 5 – Práce s přerušením, zpracování stisku tlačítka
Příklady k procvičení 1. Upravte program tak, aby při stisku tlačítek SW2, SW3 a SW4 se zapínalo/vypínalo blikání také pro LED2, LED3 a LED4. Máme tedy zajistit, aby tlačítka SW2, SW3 a SW4 zapínala/vypínala blikání pro diody LED2, LED3 a LED4 stejně jako to dělá SW1 pro LED1 v ukázkovém programu výše. 2. Přidejte možnost změny periody blikání pomocí tlačítek SW2 a SW3. Tlačítkem SW2 se perioda zmenší, stiskem SW3 se zvětší. K tomu upravte podprogram cekej tak, aby jako vstupní parametr dostal délku požadované prodlevy – parametr využijte jako číslo nahrané do reg. A před návěštím n2 (počet opakování vnitřního cyklu, výchozí hodnota 18)
Doplňující zdroje [1]
Freescale: Firemní dokumentace pro mikropočítače HCS08, dostupné online: http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=S08GB&nodeId= 01624684491437EDD5
MODERNIZACE VÝUKOVÝCH MATERIÁLŮ A DIDAKTICKÝCH METOD CZ.1.07/2.2.00/15.0463,
10