Přerušovací systém


Přerušovací systém mikroprocesoru je velice užitečná a šikovná věc, někdy je ale u začátečníků velice obávaná a špatně pochopitelná. Přerušovací systém umožňuje jakousi komunikaci mezi probíhajícím hlavním programem a určitými hardwarovými částmi mikroprocesoru. Funguje to asi takto - vykonává se hlavní program a v určitém okamžiku (v závislosti na typu zdroje přerušení - viz dále) vyšle daná hardwarová část procesoru požadavek do CPU (přes řadič přerušení - viz obrázek jádra), že chce být obsloužena. Je-li přerušení od dané hardwarové části povoleno, procesor přeruší vykonávání hlavního programu a začne vykonávat program zajišťující obsluhu vniklého přerušení. Je-li program obsluhy přerušení dokončen, procesor se vrací k vykonávání hl.programu od místa, ve kterém skončil před přechodem do programu obsluhy přerušení.

Časový průběh vykonávání hlavního programu a programu obsluhy přerušení
Obr.1 Časový průběh vykonávání hlavního programu a programu obsluhy přerušení

Nejlepší bude vysvětlit si vše na příkladu - hardwarovou částí mikroprocesoru, která bude zdrojem přerušení, bude č/č 1 v režimu časovače. Budeme chtít např. zajistit nepřetržité blikání LEDky, připojené na nějaký v/v pin. Program má kromě blikání LEDky zajišťovat např. nějaké výpočty, obsluhu displeje, vysílání sériovým kanálem - prostě cokoli dalšího. LEDka bude blikat s periodou 1 sekunda a střídou blikání 1:1. Kdybychom naprogramovali blikání LEDky v hlavním programu (nejspíš pomocí zpoždění přes cykly), procesor by se 100% zabýval obsluhou LEDky a nic jiného už by nemohl vykonávat. Takové řešení by bylo nanic. Proto k tomuto účelu využijeme časovač 1. Jeho nastavením a spuštěním můžeme zajistit to, že každou půlsekundu dojde k nastavení příznakového bitu TF1, což při povoleném přerušením od časovače 1 (bit EA a ET1 je v log.1) vede k vyvolání přerušení. Takže od začátku - běží nám hlavní program během něhož třeba počítáme nějaké hodnoty a posíláme je na nějaký displej. Časovač 1 napočítá 0,5 sekundy a vyvolá přerušení. Procesor v tomto okamžiku dokončí právě prováděnou instrukci hlavního programu, zapamatuje si, u které instrukce s vykonáváním skončil a věnuje se vzniklému přerušení. Zjistí si, od kterého zdroje přerušení právě vyvolané přerušení pochází (podle toho, který příznakový bit je nastaven - viz dále) a na základě toho začne vykonávat část programu, která je uložena na adrese příslušející danému zdroji přerušení. Tyto adresy jsou jednotlivým zdrojům přerušení pevně přiděleny (viz dále). Tato část programu tak zajišťuje obsluhu přerušení - jinými slovy provádí operace, které se mají provést jen tehdy, když si to daná hardwarová část procesoru žádá; v našem případě se tato část programu provádí po té, co časovač 1 načasuje 0,5 sekundy. My tedy v této části programu (tj. v obsluze přerušení) potřebujeme blikat s LEDkou, což provedeme jednoduše instrukcí inverze CPL P1.0, kde P1.0 je pin, na kterém je LEDka připojena. Po vykonání obsluhy přerušení procesor přechází zpět do hlavního programu a pokračuje se s jeho vykonáváním tam, kde se skončilo před přechodem do části obsluhy přerušení (tj. pokračuje se od adresy instrukce, kterou si procesor zapamatoval před přechodem do obsluhy přerušení). Přechod do části programu zajišťující obsluhu přerušení si lze představit jako volání podprogramu z hlavního programu, přičemž podmínkou pro volání je právě vznik přerušení od některého ze zdrojů.
Vznik přerušení je během vykonávání hl.programu neustále procesorem monitorován (zjišťuje stavy příznakových bitů, které jsou k tomuto účelu u daných hardwarových částí určeny). Vnější přerušení je vyvoláno přítomností log.0 nebo sestupné hrany na vstupu INT0/INT1 - je pak nastaven příslušný příznakový bit IE0/IE1. Přerušení od čítače/časovače 0 a 1 je vyvoláno jeho přetečením, tj. nastavením příznak.bitu TF0/TF1. Jak příznakové bity TF0/TF1, tak i příznakové bity IE0/IE1 jsou automaticky (obvodově) vynulovány při přechodu do programu obsluhy přerušení. Přerušení od sériového kanálu je vyvoláno, je-li log.součet příznaků RI a TI roven 1. Aby uživatel mohl zjistit, jestli bylo přerušení vyvoláno příznakem RI (příjem) nebo TI (vysílání), nejsou tyto příznaky obvodově nulovány při přechodu do programu obsluhy přerušení. Uživatel tak musí v obsluze přerušení nejprve sám stanovit příčinu přerušení (od RI nebo od TI) a teprve potom příslušný příznakový bit programově vynulovat. V obslužném programu pro sériový kanál tak zároveň může programově rozhodovat o tom, která žádost (RI nebo TI) bude zpracována dříve a bude tak mít vyšší prioritu. O prioritách přerušení bude podrobně psáno dále.
POZN.: Vznik všech uvedených přerušení je podmíněn jejich povolením (na to pozor zvláště u č/č - přetečení č/č, tj.nastavení bitu TFx ještě neznamená automaticky vznik přerušení, to musí být povoleno).

Příklad,na kterém jsme si funkci přerušovacího systému výše popsali,bude lépe srozumitelný přímo ve formě výpisu programu:


;-------------------------------hlavní program--------------------------------
		org 	0
		jmp	start
		org	30h
start:		mov	tmod,#00000001B		;časovač0-mód1
		mov	th0,#high 15535		;perioda přetečení čas0 = 50ms
		mov	tl0,#low 15535
		setb	ea			;globální povolení všech přerušení
		setb	et0			;povolení přerušení od č/č0
		setb	tr0			;spuštění č/č0
		mov	r0,#10			;počítadlo pro získání intervalu 500ms

testtlacitek:	jnb	p1.0,tlac1		;hlavní činnost programu, tady je to
		jnb	p1.1,tlac2		;např.nekonečné snímání stisku tlačítek
		jmp	testtlacitek		;stisk=log.0

tlac1:		nop				;akce při stisku tlačítka 1
		jmp	testtlacitek

tlac2:		nop				;akce při stisku tlačítka 2
		jmp	testtlacitek


;------------------část programu zajišťující obsluhu přerušení-----------------
	
		org	0bh			;adresa,na kterou procesor přechází při
						;vzniku přerušení (0bh pro č/č0)	
		jmp	cas0_prerus		;kvůli nedostatku místa musí být samotný
		org	200h			;program obsluhy umístěn jinam -> odskok
						;na dané místo
cas0_prerus:	djnz	r0,obnova		;je-li 500ms,jdi na inverzi
		cpl	p1.2			;inverze log.stavu pinu,na kterem je LEDka 
						;výsledkem je blikání LEDky
		mov	r0,#10			;obnova hodnoty počítadla

obnova:		mov	th0,#high 15535		;znovunastavení obsahu č/č0 
		mov	tl0,#low 15535
		reti				;návrat z obsluhy přerušení do hl.programu

end


V obsluze přerušení se mohou používat cykly, skoky, volání atd. stejně jako v hlavním programu. Nedoporučuji ale volat (pomocí CALL a RET) z obsluhy přerušení podprogram umístěný v hlavním programu.

Dobu vykonávání programu obsluhy přerušení je dobré si hlídat, aby náhodou celková doba vykonání obsluhy nepřekročila dobu intervalu mezi vzniky přerušení. Např. má-li časovač periodu 1ms, musí být doba vykonání obsluhy přerušení kratší než 1ms, jinak by došlo k tomu, že než by stačily vykonat všechny instrukce obsluhy, došlo by k dalšímu vzniku přerušení a vykonání obsluhy předchozího přerušení by se nedokončilo (začalo by se znovu vykonávat obsluha od první instrukce).


Na začátku jsme si naznačili, že zdrojů přerušení bývá několik, u standardního mikroprocesoru 8051 je jich celkem 5. Počet zdrojů přerušení je závislý na tom, kolika a jakými hardwarovými prvky je daný mikroprocesor vybaven. Každá důležitá část mikroprocesoru chce totiž předat do CPU informaci o své vzniklé důležité události (např. přetečení u čítače/časovače, změna log.stavu na vnějším vstupu, odvysílání/přijmutí dat sériovým kanálem atd.). Počet zdrojů přerušení se tedy liší podle typu (varianty) mikroprocesoru 8051, nejvybavenější varianty 8051 mohou mít až kolem 20 zdrojů přerušení (viz tento přehled). Protože je zdrojů několik a my budeme chtít využívat pro svou aplikaci třeba jen některé nebo budeme využívat všechny, příp. opět jen některé, ale určité zdroje budeme chtít v rámci programu zakazovat podle různých podmínek, umožňuje nám mikroprocesor povolovat vznik přerušení jen od některých, námi zvolených zdrojů. K tomuto účelu je u mikroprocesoru uživateli k dispozici spec.funkční registr IE.

IE - Registr povolení přerušení (Interrupt Enable)

Rozložení bitů v registru IE

Popis jednotlivých bitů registru IE:
EA - jak písmena napovídají, jde o zkratku angl.spojení Enable All, tedy povol vše. Jedním bitem tedy můžeme naráz povolit/zakázat všechny přerušení (funkci bitu si lze představit jako sériový spínač ke všem ostatním přerušením, viz obr. 2). Je-li EA=1, mohou být přijaty žádosti o přerušení těch zdrojů, které jsou povoleny jejich danými povolovacími bity (EXx, ETx, ES atd.) Je-li EA=0, pak nemůže být přijata žádná žádost o přerušení (nastavení samotných bitů EXx, ETx, ES ještě nepovoluje vyvolání přerušení). Bit EA tedy jinými slovy funguje jako globální povolení všech přerušení. Všechny ostatní bity v registru IE slouží k individuálnímu povolování daných přerušení (viz následující popis).

EX0, EX1 - povolení vnějšího přerušení INT0, INT1. Je-li EXn=1, je povoleno přerušení od vnějšího vstupu INTn. O tom, zda bude přerušení vyvoláno sestupnou hranou signálu nebo úrovní log.0 na daném vstupu (INTn), rozhoduje nastavení bitu ITn v registru TCON.

ET0, ET1 - povolení přerušení od čítače/časovače 0,1. Je-li ETn=1, je povoleno přerušení způsobené přetečením č/č n.

ES - povolení přerušení od sériového kanálu. Je-li ES=1, je povoleno přerušení od příjmu a vysílání sériového kanálu.

POZN: U všech pěti výše uvedených povolovacích bitů platí to, co jsme si řekli dříve, a to že k povolení daného přerušení je nutné nastavení bitu EA do log.1.

Nastavením bitů v registru IE jsme tedy povolili přerušení od námi požadovaných zdrojů. Jestliže jich povolíme několik, vyvstává otázka, co se stane, když přijde do CPU procesoru více žádostí o přerušení ve stejný okamžik (např. ve stejnou dobu přijde žádost o přerušení od čítače 1 a žádost o přerušení od sériového kanálu). Která žádost tedy bude mít přednost a bude zpracována jako první? Protože můžou přijít žádosti o přerušení klidně i od všech pěti zdrojů naráz, musí být nějakým způsobem zajištěno postupné zpracování všech vzniklých přerušení - jinými slovy musí existovat systém priority, který jasně řekne, které přerušení bude obslouženo jako první, které jako další a které bude obslouženo jako poslední. U mikroprocesoru je systém priority přerušení řešen tak, že jednotlivé zdroje přerušení mají pevně přidělenou prioritu v každé ze dvou programově volitelných úrovní priorit. Tyto dvě úrovně budeme označovat jako vyšší a nižší. V rámci těchto úrovní (nižší nebo vyšší) má nejvyšší prioritu vnější přerušení INT0 (příznakový bit IE0), po něm následuje přerušení č/č 0 (bit TF0), dále je vnější přerušení INT1 (bit IE1), dále je č/č 1 (bit TF1). Nejnižší prioritu má přerušení od sériového kanálu (bity RI a TI). Toto pevné přidělení priorit v dané úrovni bývá někdy nazýváno jako přirozená priorita. Díky pevnému stanovení priorit víme přesně sled zpracování vzniklých přerušení.
Někdy nám ale pevně daný sled nemusí vyhovovat a my bychom potřebovali přiřadit přerušením priority v jiném pořadí. Např. budeme potřebovat dát nejvyšší prioritu vnějším přerušením INT0 a INT1, pak teprve budou následovat č/č 0 a 1 a sériový kanál. Abychom toho mohli dosáhnout, existují proto výše zmíněné 2 úrovně priorit. Přerušení, která jsou přepnuta do vyšší úrovně, budou zpracovány jako první, přerušení v nižší úrovni budou zpracovány až poté, co budou zpracována všechna přerušení s vyšší prioritou (=přepnutá do vyšší úrovně). Proto pro náš příklad vnější přerušení INT0 a INT1 přepneme do vyšší úrovně priority, zbylá přerušení necháme v nižší úrovni přerušení. A protože je v dané úrovni priorita přerušením přidělena pevně, dosáhneme toho, že jako první budou zpracována vnější přerušení INT0 a INT1, z toho INT0 bude zpracováno před INT1 dle pevné priority, po těchto přerušeních budou zpracována přerušení v nižší úrovni, tj. č/č0, č/č1 a sér.kanál, přičemž jako první bude zpracováno přerušení č/č0 a jako poslední přerušení od sér.kanálu (dle pevné priority).
Přiřazení vyšší priority (=přepnutí do vyšší úrovně) jednotlivým zdrojům přerušení se provádí nastavením odpovídajících bitů v registru spec.funkcí IP.

IP - Registr priority přerušení (Interrupt Priority)

Rozložení bitů v registru IP
Popis jednotlivých bitů registru IP:
PS - nastavením bitu se přerušení od sér.kanálu přepne do vyšší úrovně priority
PT1 - nastavením bitu se přerušení od č/č 1 přepne do vyšší úrovně priority
PX1 - nastavením bitu se vnější přerušení INT1 přepne do vyšší úrovně priority
PT0 - nastavením bitu se přerušení od č/č 0 přepne do vyšší úrovně priority
PX0 - nastavením bitu se vnější přerušení INT0 přepne do vyšší úrovně priority


Schématické zobrazení přerušovacího systému 8051
Obr.2 Schématické zobrazení přerušovacího systému 8051

Přiřazením vyšší úrovně priority danému přerušení dosáhneme toho, že v případě vzniku více žádostí o přerušení v jeden okamžik dostane přednost žádost od zdroje s vyšší prioritou. Dále platí, že probíhá-li obsluha přerušení s nižší prioritou a vznikne žádost o přerušení s vyšší prioritou, bude probíhající přerušení s nižší prioritou přerušeno a začne se vykonávat obsluha přerušení s vyšší prioritou. Po dokončení obsluhy přerušení s vyš.prior. se procesor navrací k vykonávání obsluhy přerušení s nižší prioritou.
Je-li již jedno přerušení vyvoláno (probíhá obslužný program), nemůže být toto přerušení přerušeno přerušením s vyšší prioritou v dané úrovni priority (dle tabulky přirozené priority) a musí počkat na jeho dokončení. Potom budou podle vzájemné (=pevné=přirozené) priority v dané úrovni postupně zpracovány další žádosti o přerušení. Z uvedeného vyplývá, že přerušení s vyšší úrovní priority už nemůže být žádným dalším přerušením přerušeno.
Pokud budeme v programu používat jeden nebo dva zdroje přerušení, není otázka priority kritická. Pokud ale budeme používat zdrojů třeba všech pět, co máme u 8051 k dispozici nebo budeme používat variantu mikroprocesoru např. s více než 10 zdroji, bude správná volba priority velmi důležitá. Z tohoto důvodu mají takovéto mikroprocesory k dispozici až 4 úrovně priority, což uživateli i při tak velkém počtu zdrojů přerušení umožňuje rozumně nakonfigurovat priority přerušením. Co se týče nastavení priorit přerušením, nelze vnutit obecný recept na správnou volbu, uživatel musí vždy sám zvážit podle dané aplikace, který zdroj přerušení je pro něj důležitý a který méně.

Na začátku tohoto povídání jsme si řekli, že po vzniku žádosti o přerušení (v případě jeho povolení) je vykonávání hl.programu přerušeno a přechází se do části programu, jež zajišťuje obsluhu vzniklého přerušení. Tato část programu tak bývá i označována - tj. jako obsluha přerušení. Řekli jsme si, že procesor po zjištění zdroje přerušení přechází na adresu příslušející danému zdroji. Tato adresa ukazuje na paměťové místo (v paměti programu), kde se bude nacházet obsluha přerušení. Tyto adresy jsou jednotlivým zdrojům přerušení pevně přiřazeny (viz tabulka níže). Protože jsou ale adresy od sebe vzdáleny o pouhých 8 bytů, není dobré umísťovat podprogram obsluhy přerušení hned od této adresy (vektoru), protože je velmi pravděpodobné, že obsluha přerušení bude zabírat mnohem více než oněch 8 bytů. Proto se na adresu vektoru přerušení umísťuje pouze instrukce nepodmíněného skoku (xJMP) směřující na vlastní obslužný program umístěný na jiném paměťovém místě. Vše je dobře vidět na výše uvedeném příkladu výpisu programu - adresu vektoru přerušení je zde 0bH, následuje odskok přes JMP na vlastní podprogram obsluhy, který je uložen od adresy 200H. Podprogram obsluhy přerušení musí být ukončen instrukcí RETI, čímž se činnost procesoru vrací zpět k vykonávání hl.programu.

Tab.1  Vektory přerušení (adresy obsluhy) mikroprocesoru 8051

Zdroj přerušení
Adresa
Příznak
Význam
IE0 Vnější přerušení 0 0003H
TF0 Čítač / časovač 0 000BH
IE1 Vnější přerušení 1 0013H
TF1 Čítač / časovač 1 001BH
RI + TI Sériový kanál 0023H


POZN: Jak je vidět z tabulky adres příslušejících zdrojů přerušení (vektory přerušení), nejvyšší adresa má hodnotu 23H. Z tohoto důvodu (rezervace několika prvních adres v paměti programu pro vektory přerušení) bývá hl.program umístěn v programové paměti až za těmito adresami. Vezmeme-li nejnepříznivější případ, kdy budeme používat i sériový kanál s přerušením, tzn. bude se užívat adresa 23H a dále, že na této adrese musí být umístěna alespoň instrukce xJMP (nejdelší LJMP zabere 3 byty), můžeme hl. program umístit až od adresy 26H. Pokud budeme psát program pro mikroprocesor 8052, nesmíme zapomenout, že u něj je o jednu adresu víc (2BH) - pro č/č 2. U mikroprocesoru 8052 tak můžeme hl.program umístit až od adresy 2EH, v případě že budeme č/č 2 používat. Já osobně už pak raději používám kulatou adresu 30H ,a to i pro 8051. Tady je ještě dobré upozornit na to, že některé překladače si dokážou umístění hl.programu a podprogramů uspořádat sami, uživateli pak stačí v programu zaadresovat začátek hl.programu (ORG 0) a podprogramy obsluhy přerušení (ORG 03H, 0BH, ...). Nevýhodou tohoto ale je, že programátor přesně neví, co je kde uloženo (záleží na možnostech překladače) - více informací zde.


Další důležitou věcí při práci s přerušeními je to, že si musíme uvědomit, která paměťová místa mezi sebou hl.program a podprogram obsluhy přerušení sdílejí a která paměťová místa nebo příznakové bity může hl.program ovlivňovat, aniž by to podprogram obsluhy věděl a naopak. Paměťovými místy je zde myšlen registr R0 až R7, Acc, B, DPTR atd. Může totiž nastat (a ve většině programů taky nastává) situace, že s danými paměť.místy pracujeme jak v hl.programu, tak v obsluze - typicky alespoň Acc. Např. v hl. programu provádíme nějaký výpočet, ve kterém používáme pro úschovu A (akumulátor), v obsluze s akumulátorem děláme úplně něco jiného a třeba ho ještě rotujeme... Pak může nastat toto - v půlce výpočtu v hl. programu vznikne přerušení a přejde se do obsluhy, kde se A využívá k něčemu jinému. Původní hodnota A se tak přemaže nebo se s ní v obsluze počítá (tj. s nesprávnou hodnotou). Po dokončení podprogramu obsluhy zůstane v A nějaká nová hodnota a řízení se vrací zpět k vykonávání hl. programu - tedy pokračuje se v započatém výpočtu. A tady pak vznikne chyba 100-procentně - pokračuje se ve výpočtu s novou - změněnou hodnotou A. Pak se nestačíme divit, kde je chyba a jak to že nám program nefunguje. Abychom se tomuto problému vyhnuli, je dobré na začátku každé obsluhy přerušení si uvědomit, které paměť.místa budeme v obsluze ovlivňovat (měnit,ničit) a tyto místa hned na začátku obsluhy uložit do zásobníku. Na konci obsluhy tyto paměť.místa zase ze zásobníku obnovit. Hodnoty paměť.míst z hl.programu tak zůstanou zachovány. Totéž platí pro příznakové bity C,AC,OV,P. I ty je dobré dle potřeby uschovat do zásobníku, abychom neovlivnily výsledky nejen aritmetických operací prováděných v hl.programu/obsluze. Protože může dojít k přerušení již vzniklého přerušení (vlivem vyšší priority), může se nám i díky tomu zásobník rychle zaplnit větším množstvím dat. Proto je důležité rezervovat pro zásobník dostatek paměťového místa - podle toho, kolik bytů uschováváme a jestli může dojít k přerušení již vzniklého přerušení. Je třeba též pamatovat na to, že zásobník se používá i k jiným účelům - uložení návratových adres při voláních atd. A s tím souvisí i další věc - musíme dodržet pravidlo, že kolik registrů na začátku obsluhy přerušení schováme (přes PUSH), tolik jich musíme na konci obsluhy ze zásobníku zase obnovit (přes POP). Pokud bychom obnovili jiný počet než který jsme schovali, došlo by k chybnému nastavení ukazatele zásobníku, což by mělo za následek při vykonání instrukce RETI vyzvednutí jiné návratové adresy, než která byla uložena při přechodu do obsluhy přerušení (návratová adresa se ukládá také do zásobníku). A další "nevysvětlitelná" chyba programu by byla na světě...

Následující příklad sice není ideální, ale alespoň nastiňuje způsob úschovy ovlivňovaných registrů.

                org     0
                jmp     start
                org     30h
start:          mov     tmod,#00000001B     ;časovač0-mód1
                mov     th0,#high 15535     ;perioda přetečení čas0 = 50ms
                mov     tl0,#low 15535
                setb	ea                  ;globální povolení všech přerušení
                setb	et0                 ;povolení přerušení od č/č0
                setb	tr0                 ;spuštění č/č0

testtlacitek:   jnb     p1.0,tlac1          ;hlavní činnost programu, tady je to
                jnb     p1.1,tlac2          ;např.nekonečné snímání stisku tlačítek
                jmp     testtlacitek        ;stisk=log.0

tlac1:          mov     b,#100              ;akce při stisku tlačítka 1 - prevod bin->BCD
                div     ab			
                mov     60h,a		
                mov     a,#10			
                xch     a,b
                div     ab
                swap    a
                add     a,b
                mov     61h,a		
                jmp     testtlacitek

tlac2:          mov     a,31h               ;akce při stisku tlačítka 2 - 16-bit scitani
                add     a,41h
                mov     51h,a
                mov     a,30h
                addc    a,40h
                mov     50h,a						
                jmp     testtlacitek
		

;------------------část programu zajišťující obsluhu přerušení-----------------
	
                org     0bh	                ;adresa,na kterou procesor přechází při
                                            ;vzniku přerušení (0bh pro č/č0)	
                jmp     cas0_prerus         ;kvůli nedostatku místa musí být samotný
                org     200h                ;program obsluhy umístěn jinam -> odskok
                                            ;na dané místo
cas0_prerus:    push    acc
                push    b
                push    psw


                nop                         ;a teď si můžu s A,B,C,OV atd. dělat co chci
                nop                         ;a jejich původní hodnota pro hl.program po 
                nop                         ;skončení obsluhy přerušení zůstane nezměněna

                mov     a,#20               ;ukázky instrukcí, které by nám zničily původní
                clr     c                   ;hodnotu daného registru nebo příznak.bitu, pokud
                mul     ab                  ;bychom jej neschovali do zásobníku

                pop     psw
                pop     b
                pop     acc	

obnova:         mov     th0,#high 15535     ;znovunastavení obsahu č/č0 
                mov     tl0,#low 15535
                reti                        ;návrat z obsluhy přerušení do hl.programu

end


Podrobnější popis vyřízení žádosti o přerušení

Žádosti o přerušení (příznaky IE0,IE1,TF0,TF1,RI+TI) se vzorkují v době S5P2 každého strojového cyklu procesoru a vyhodnocují se v následujícím cyklu. Je-li některý z příznaků nastaven a není splněna žádná z podmínek zabraňujících vyvolání obslužného podprogramu, přerušovací systém provede instrukci LCALL (dlouhé volání podprogramu) na příslušnou adresu určenou tab.1. Kromě individuálního nebo globálního zakázání přerušení v registru IE, může jeho vyvolání oddálit:
  1. právě probíhající přerušení se stejnou nebo vyšší úrovní priority,
  2. doposud nedokončená instrukce
  3. právě probíhající instrukce RETI (návrat z přerušení) nebo instrukce zapisující do registrů IE a IP
Druhá podmínka zajišťuje, že před přechodem do obslužného podprogramu se rozdělaná instrukce nejprve dokončí. Třetí podmínka zajišťuje, že po instrukci RETI nebo instrukci zasahující do registrů IE a IP je vykonána ještě jedna instrukce a teprve potom je provedeno směrování na příslušný vektor přerušení. Cyklus vyhodnocení se opakuje v každém strojovém cyklu a vyhodnocují se v něm platné (navzorkované) hodnoty v periodě S5P2 předchozího strojového cyklu. Není-li žádost o přerušení obsloužena, protože byla platná některá z blokovacích podmínek, pak v době, kdy už není aktivní se neobslouží, i když podmínky blokování zanikly. Žádost neobslouženého příznaku přerušení se nikde neuchovává (vyjma příznaku), a v každém cyklu vyhodnocení se pracuje s novými hodnotami získanými v předcházejícím strojovém cyklu. Aby vzorkování vnějších přerušení bylo správné, musí při aktivaci přerušení sestupnou hranou trvat hodnota log.1 i log.0 na vstupech alespoň jeden strojový cyklus. V případě aktivace nízkou úrovní signálu, musí žádost trvat tak dlouho, dokud nedojde k přechodu do obslužného podprogramu. Nebude-li žádost v průběhu obslužného podprogramu zrušena, potom dojde k opětovnému vyvolání přerušení.

Časový průběh odezvy na přerušení (nejrychlejší možná odezva)
Obr. 3 Časový průběh odezvy na přerušení (nejrychlejší možná odezva)

Na obr.3 je zobrazena situace při přijetí žádosti o přerušení v případě, kdy procesor zpracovává jednocyklové instrukce nepracující s registry IE a IP. V cyklu C1 před periodou S5P2 přichází žádost o přerušení, která se vyhodnocuje v cyklu C2. Jsou-li splněny všechny podmínky pro vyvolání přerušení, potom v cyklech C3 a C4 je generována instrukce LCALL na příslušnou adresu obslužného podprogramu. V cyklu C5 potom může být zpracována první instrukce obslužného podprogramu. Vznikne-li žádost o přerušení s vyšší prioritou před periodou S5P2 strojového cyklu C3, potom bude přerušení obslouženo podle výše uvedených pravidel během strojových cyklů C5 a C6, aniž se vykoná jediná instrukce obslužného podprogramu s nižší prioritou. Mezi vznikem požadavku na přerušení a první instrukcí obslužného programu proběhnou nejméně tři strojové cykly. Odezva na přerušení se prodlouží při platné podmínce blokující přechod do obslužného podprogramu. V případě probíhajícího přerušení se stejnou nebo vyšší úrovní priority, je doba čekání závislá na délce a vlastnostech obslužného podprogramu. Není-li vyhodnocení žádostí prováděno v posledním cyklu instrukce, potom prodloužení odezvy nebude větší než 3 strojové cykly (instrukce MUL a DIV trvají 4 cykly). Probíhá-li právě instrukce RETI nebo instrukce operující s IE nebo IP, prodlouží se doba odezvy nejvíce o 5 strojových cyklů (1 cyklus pro dobíhající instrukci a 4 cykly za dokončení nejdelší následující instrukce MUL nebo DIV). Využíváme-li v systému pouze jedno přerušení, potom časová odezva bude vždy delší než 3 a kratší než 9 strojových cyklů.


POZN: Protože následující informace nevyplynula z výše popsaného systému priority a není ani z textu vyvoditelná, musíme si ji připomenout ještě zde nakonci - úplně nejvyšší prioritu ze všech možných zdrojů přerušení má reset (nulování) mikroprocesoru. Adresa (vektor) obsluhy je 0H. Touto adresou proto začíná každý program (ve formě pseudoinstrukce ORG 0H) - na tuto adresu přechází CPU při vykonávání programu po zapnutí nebo resetu mikroprocesoru.


Zpět na hlavní stránku povídání

Copyright © Michal Fuksa 2002