AVR - Atmega i vanjski prekid

slika_hardver

Vanjski prekid označava poziv za izvršavanje odgovarajuće prekidne rutine (potprograma) od strane vanjskog uređaja koji je priključen na mikrokontroler. Podešavanjem i kontrolom pojedinih bitova u odgovarajućim registrima može se detekovati poziv za prekid i dozvoliti ili ne izvršavanje odgovarajuće prekidne rutine. U ovom članku biće izvršena demostracija pozivanja prekidne rutine pritiskom na taster koji je povezan na mikrokontroler, pri čemu će se paliti ili gasiti led dioda, zavisno od prethodnog stanja.

Šema spoja mikrokontrolera i potrebnih elektronskih komponenti prikazana je na slici:

slika_shema

(klikni da uvećaš)

 

Prije nego što se počne pisanje programskog koda, potrebno je obratiti pažnju šta se dešava sa kontaktima tastera prilikom pritiska ili otpuštanja tastera. Pritiskom, držanjem ili otpuštanjem tastera, s obzirom da se radi o mehničkim kontaktima, javljaju se mehaničke vibracije koje mogu u vrlo kratkom vremenskom trenutku nekoliko puta spojiti i otpojiti kontakte tastera, što predstavlja prelazni režim ili tzv. bounce efekat. Ovaj efekat je prikazan na sljedećoj slici:

 

slika_taster

 

 

Sa slike se vidi razlika između idealne i realne karakteristike pritiska na taster. Prelazni režim traje nekoliko milisekundi i može se izbjeći njegov uticaj uvođenjem kašnjenja od nekoliko milisekundi u programski kod, što će biti ovdje i urađeno. Takođe postoji i hardversko rješenje primjenom dodatnih elektronskih komponenti o čemu ovdje neće biti riječi, jer kašnjenje od nekoliko milisekundi ne predstavlja problem.

Ideja programa je da se pritiskom na taster naizmjeničko pali ili gasi led dioda, zavisno u kakvom je stanju bila prije pritiska na taster. Za vrstu vanjskog prekida koristi se poziv prekida pri promjeni logičkog stanja na pinu na kojem se nalazi taster. Pull up otpornik na pinu PC4 je uključen, tako da je ovaj pin preko tog otpornika postavljen na logičku jedinicu, pritiskom na taster pin se postavlja na logičku nulu što dovodi do poziva prekida. Otpuštanjem tastera dolazi ponovo do promjene logičkog stanja (sa 0 na 1) što ponovo dovodi do poziva prekidne rutine.

Prema tome, ako je na početku led dioda upaljena, pritiskom na taster led dioda se ugasi, a otpuštanjem tastera ponovo se upali.

Ukoliko se tater otpusti u toku izvršavanja prekidne rutine, tada će odgovarajuća zastavica (fleg) biti postavljena na logičku jedinicu, što znači da će prekidna rutina biti ponovo pozvana kada se steknu svi potrebni uslovi, tj. kada se završi trenutna prekidna rutina i omogući globalni i odgovarajući interapt. Resetovanjem zastavice tj. postavljanjem flega na logičku nulu programskim putem prije izlaska iz prekidne rutine, sprečava se ponovno izvršavanje prekidne rutine. To znači kratoktrajnim pritiskom na taster led dioda će promjeniti svoje stanje.

Ukoliko se taster otpusti nakon završetka prekidne rutine, prekidna rutina će se ponovo izvršiti.

Izgled programskog koda:


/********************************
*        Led Blink               
*                               
*    Naziv: Prekid.c               
*     Autor: Elektrospin.info       
*     Datum: 29.05.2009           
*     Mikrokontroler: ATmega48   
*                   
********************************/


#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

// Prekidna rutina za prekidac
ISR(PCINT1_vect)
{
    // promjena stanja led diode
    if(PIND & (1<<PD4))
        PORTD &= ~(1<<PD4);
    else
        PORTD |= (1<<PD4);
   
// Kašnjenje zbog vibracije kontakata tastera
    uint8_t i;
    for(i=0;i<10;i++)
    _delay_ms(20);

// Ako je taster do ovog trenutka otpusten, fleg je postavljen na 1
// resetovanjem ovog flega sprecava se ponovno izvrsavanje prekidne rutine

// led dioda neće promjeniti svoje stanje otpustanjem tastera

// fleg se resetuje upisivanjem logicke jedinice na njegovo mjesto

    if(PCIFR & (1<<PCIF1))
        PCIFR |= (1<<PCIF1);
}


int main(void)
{
    // inicijalizacija prekidaca
    PORTC |= (1<<PC4); // pull-up zbog prekidaca na masu
    PCICR |= (1<<PCIE1); // tip prekida „Pin Change Interrupt“
    PCMSK1 |= (1<<PCINT12); // pin na kome se poziva prekid

    // inicijalizacija za led diodu
    DDRD |= (1<<PD4);
    PORTD |= (1<<PD4); // upali Led diodu
   
    sei(); //omoguci globalni prekid

    // startuj beskonacnu petlju
        while(1);
}

 

Program je kreiran za AVR 8-bitni mikrokontroler Atmega48, analogno vrijedi i za bilo koji drugi atmelov AVR mikrokontroler.Kreiranje projekt, pisanje programskog koda, podešavanje AVR studia i prevođenje programskog koda objašnjeno je u prethodnom članku (klikni ovdje).