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í.
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í
hlavního 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, 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)
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)
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
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í
hlavního 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í hlavního 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 |
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í na další stránce.
|
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ěťová 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:
- právě probíhající přerušení se stejnou nebo vyšší úrovní priority,
- doposud nedokončená instrukce
- 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í.
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ů.
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 na konci - ú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.
|
|
© DH servis 2002 - |