Pergés (Prell)
Az ideális kapcsoló megnyomáskor az áramkört azonnal zárja, felengedéskor pedig azonnal nyitja. A valóságban a mechanikus kapcsolók rugalmas fém alkatrészeket tartalmaznak, ezért a kapcsoláskor rezgés keletkezik az érintkezőknél. Emiatt be és kikapcsolásakor a kapcsolás után rövid ideig (néhány ms-ig) a nyitott, és a zárt állapot között oszcillál (lásd az alábbi ábra a) pontját). A mindennapi életben ezt mi nem vesszük észre, de a mikrovezérlő ez alatt a néhány ms alatt akár több ezer műveletet is el tud végezni, és ha egy lefutó élre adtunk meg megszakítást, akkor egy gombnyomás után többször fog a megszakításrutin lefutni. Ezért ezt kiküszöbölendő, valamilyen pergésmentesítő módszert kell alkalmaznunk.
Alapvetően kétféle módszerrel lehet a pergést megszüntetni:
Az alábbi ábrán látható néhány hardveres megoldás. Ha a nyomógombbal párhuzamosan kötünk egy kondenzátort ( b) pont), akkor az mintegy elnyeli a pergés során keletkező impulzusokat, de egyben egy rezgőkört is alkot, és egy negatív feszültség tüske is jelenkezik amit nem szeret a mikrovezérlő. Erre megoldás lehet ha egy másik ellenállást sorba kötünk a kondenzátorral ( c) pont). Az igazán jó megoldás egy Schmitt-trigger használata ( d) pont).
A fent vázolt hardveres pergésmentesítés addig jó, amíg csak kevés számú nyomógombot akarunk használni. Egy 4x4-es nyomógomb mátrixnál már elég nehézkes a megvalósítása. Ekkor a szoftveres pergésmentesítés célravezetőbb lehet. Nézzünk erre is egy példát.
Szoftveresen a legegyszerűbb megoldásnak az tűnhetne, ha a megszakításrutinba egy várakozást építenénk be, és a rutinban a további megszakításokat letiltanánk, hogy a program csak a gomb első megnyomására reagáljon.
De korábban már említettem, hogy az ISR-nek a lehető leggyorsabbnak kell lennie, hogy az időzítésre érzékeny programrészek ne szálljanak el. Ezért az ISR-be nem tanácsos késleltetéseket rakni, hanem csak egy változó értékét érdemes inkább megváltoztatni, amit majd a megszakításrutinon kívül, a főprogramban figyelünk, és változása esetén a késleltetéseket a főprogramon belül hajtjuk végere.
Az alábbi kódban pont ezt történik. Az ISR-en belül átkapcsoljuk a LED-et és letiltjuk a további megszakításokat, hogy ne fusson le többször az ISR, majd az ISR-en kívül a főprogramban végezzük el a késleltetést a pergés megszüntetése érdekében.
/* Interrupt teszt 2
Nyomogomb: a PD2 labon (INT0)
LED: a C0 labon
*/
#define F_CPU 1000000UL // 1 MHz CPU clock
#include <util/delay.h> // Idozito, keslelteto rutinokat tartalmazo fajl
#include <avr/io.h> // AVR konstansokat, baallitasokat tart. fajl
#include <avr/interrupt.h> // Megszakitasokat kezelo rutinokat tart. fajl
ISR (INT0_vect) // INT0 megszakitas kiszolgalo rutin utasitasai
{
PORTC ^= (1<<PC0); // PC0 lab allapotat megcsereli (LED be/ki)
GICR &= ~(1<<INT0); // INT0 letiltasa (nyomogomb perges megakadalyozasa erdekeben)
}
int main (void) // Program eleje
{
// portok beallitasa
DDRC |= (1<<PC0); // PC0 kimenet
PORTC |= (1<<PC0); // PC0 labra +5V (LED1 kikapcsolva)
PORTD &= ~(1<<PD2); // PD2 bemenet
PORTD |= (1<<PD2); // PD2-hoz tartozo felhuzoellenallas be
// az INT0 kulso interrupt beallitasa
GICR |= (1<<INT0); // INT0 engedelyezese (PD2-es lab)
MCUCR |= (1<<ISC01); // a lab lefuto elre adjon megszakitast
sei(); // megszakitasok bekapcsolasa
while (1)
{
// Ha INT0 megszakitas ki van kapcsolva, akkor egy kis varakozas utan bekapcsoljuk
if((GICR & (1<<INT0)) == 0)
{
// varakozas nehany szaz ms-ig, amig a nyomogomb befejezi a pergest
_delay_ms(250);
// minden tovabbi varakozo megszakítás torlese, majd a megszakitasok engedelyezese
GIFR |= (1<<INTF0); // INT0-hoz tartozo jelzobit torlese
GICR |= (1<<INT0); // INT0 megszakitas engedelyezese
}
};
}
A szoftveres pergésmentesítés után most már helyesen működik a nyomógomb.
A cikk még nem ért véget, lapozz!
Értékeléshez bejelentkezés szükséges!