Vaja 5: EXTI
Namen tokratne vaje je, da se spoznate s prekinitvami, ki jih lahko preko periferne naprave EXTI prožijo GPIO pini.
Naprava EXTI
Extended Interrupt and Event Controller (EXTI) omogoča generiranje prekinitev z zaznavanjem front na vhodnih linijah. Omogoča tudi zbujanje procesorja iz stanje nizke porabe (low-power modes). Poenostavljena shema je prikazana na Slika 6.1.
Vhodna linija je povezana v enoto, ki zaznava fronti na vhodu. Zaznavamo lahko prvo (angl. rising edge) in/ali zadnjo fronto (angl. falling edge). Zaznavanje prve fronte se vklopi v registru EXTI_RTSR
(Rising trigger selection register), zaznavanje zadnje fronte pa v registru EXTI_FTSR
(Falling trigger selection register). V registru EXTI_IMR
(Interrupt mask register) omogočimo, da se zaznana fronta zabeleži v register EXTI_PR
(Pending register). V primeru, da je bit v tem registru postavljen, to sproži zahtevo po prekinitvi prekinitvenemu krmilniku NVIC za EXTI linijo.
Naprava SYSCFG
Kot smo že povedali, ima STM32H750 176 GPIO pinov. Vsak pin nima svoje EXTI linije, saj so pini preko naprave SYSCFG (System Configuration) združeni v 16 EXTI linij. Kot prikazuje Slika 6.2, so vsi pini z oznako 0 (PA0, PB0, PC0, …, PK0) preko multiplekserja povezani na linijo EXTI0
. Vsi pini z oznako 1 so povezani na linijo EXTI1
, in tako dalje do linije EXTI15
, na katero so povezani vsi pini z oznako 15.
Prekinitve EXTI
Naprava EXTI uporablja 7 prekinitvenih vhodov prekinitvenega krmilnika NVIC. Linije EXTI0
, EXTI1
, EXTI2
, EXTI3
in EXTI4
imajo vsak svojo prekinitveno linijo, linije EXTI5
do EXTI9
so skupaj povezane na skupno linijo, preostale linije EXTI10
do EXTI15
pa na drugo skupno linijo. Spodnja tabela povzema informacije o EXTI linijah ter pripadajočih prekinitvenih oznakah in imeni prekinitveno servisnih programov.
EXTI linija | Prekinitvena oznaka | Prekinitveno servisni programi |
---|---|---|
EXTI0 | EXTI0_IRQn | EXTI0_IRQHandler |
EXTI1 | EXTI1_IRQn | EXTI1_IRQHandler |
EXTI2 | EXTI2_IRQn | EXTI2_IRQHandler |
EXTI3 | EXTI3_IRQn | EXTI3_IRQHandler |
EXTI4 | EXTI4_IRQn | EXTI4_IRQHandler |
EXTI5, EXTI6, EXTI7, EXTI8, EXTI9 | EXTI9_5_IRQn | EXTI9_5_IRQHandler |
EXTI10, EXTI11, EXTI12, EXTI13, EXTI14, EXTI15 | EXTI15_10_IRQn | EXTI15_10_IRQHandler |
Programski vmesnik EXTI
Vklop in uporabo prekinitve EXTI naredimo v treh korakih, ki so prikazani spodaj. Za primer je uporabljen pin PD4
.
2. vklop prekinitve v NVIC
Prekinitev vklopimo tako kot smo spoznali na zadnji vaji, z uporabo funkciji za nastavitev prioritete in vklopa prekinitve.
(EXTI4_IRQn, 12, 0);
HAL_NVIC_SetPriority(EXTI4_IRQn); HAL_NVIC_EnableIRQ
3. implementacija prekinitveno servisnega programa.
V prekinitveno servisnem programu moramo ob koncu pobrisati prekinitveno zahtevo v EXTI napravi. To storimo z makrojem __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_x)
, ki pobriše bite v registru EXTI_PR
. Če zahteve ne pobrišemo, se bomo v prekinitveno servisni program vrnili takoj po izhodu. Naprava EXTI namreč zahteve po prekinitvi ne umakne samodejno.
Pri prekinitvah, ki se prožijo iz več linij, je smiselno preveriti katera izmed linij je sprožila prekinitev. To storimo z __HAL_GPIO_EXTI_GET_IT(GPIO_PIN_x)
.
Primer PSP-ja:
void EXTI4_IRQHandler(void) {
// Preverimo, da je pin 4 sprozil prekinitev
// Nujno potrebno pri liniah 5 do 15
if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_4)) {
// Pobrisemo EXTI4 pending bit in EXTI pending register
(GPIO_PIN_4);
__HAL_GPIO_EXTI_CLEAR_IT}
}
Odboj gumba
Pri enkratnem pritisku gumba bi pričakovali, da na vhodu preberemo eno fronto, ki se zgodi ob prehodu iz logične ničle na logično enico. V realnosti pa se zgodi, da zaradi t.i. odboja gumba (angl. button bounce) na vhodu preberemo več front. Slika 6.3 prikazuje primer odboja gumba ob enkratnem pritisku. Kot vidimo se na vhodu zgodijo tri fronte, relativno hitro ena za drugo. Na to moramo biti pozorni pri realizaciji prekinitveno servisnega programa.
Odpravljanju tega pojava rečemo button debounce. Najenostavnejša rešitev je, da ob prekinitvi, ki jo sproži gumb, preverimo da je od zadnje prekinitve minilo zadosti časa (npr. več kot 50ms). Prekinitev, ki se zgodi nekaj milisekund po zadnji prekinitvi enostavno ignoriramo (zgolj pobrišemo zahtevo).
Naloga 4
Napišite program v katerem naj se proži prekinitev ob pritisku gumba. Ob prvem pritisku (prvi fronti) gumba naj se prižgeta zeleni LED diodi, ob drugem pritisku naj se ugasnita, pri tretjem zopet prižgeta, in tako dalje. Ob koncu pritiska gumba preverite ali je od pritiska minilo več kot 5 sekund. Če je, prižgite rdečo LED. Odpravite tudi odboj gumba.