External Interrupt

Tillbaka till startsidan

 

Prova interrupt. Här följer ett exempelpå ett program till ATmega som växlar en lysdiod, LED, På/Av för varje knapptryckning, och som utnyttjar interrupt.

Knappen ansluts mellan pinne 4, INT0/PD2, och jord. När man trycker på knappen blir insignalen "0", när man släpper knappen så kommer insignalen i stället från ett så kallat "Pull Up" motstånd och blir då "1". Utan PullUp motståndet hade ingången lämnats helt "öppen" när man släppt knappen, och då varit känslig för störningar från omgivningen och funktionen hade blivit mycket osäker.
PullUp-motståndet innebär en viss kostnad, så därför finns det en möjlighet att programmera chippet till att använda "inbyggda" PullUp motstånd. Om en pinne är programmerad till ingång, och man därefter skriver ut "1" till pinnen så kopplas det interna PullUp-motståndet in.

DDRD  &= ~( 1 << PD2 );      // pin 4 PD2 direction is input, Butt (INT0)
PORTD |=  ( 1 << PD2 );      // Enable pullup resistor for INT0

ATmega har vektoriserat interrupt. Det finns 24 olika interruptkällor, och varje källa styrs till en egen interruptrutin.

Vid interrupt så körs motsvarande interruptrutin. Medan en interruptrutin körs är fortsatta interrupt avstängda.

För att använda external interrupt INT0 så skriver man en interrupt rutin:

#include <avr/interrupt.h>

ISR( INT0_vect )
{
   /* write your interrupt subroutine here */ 
}

Interrupt enablas på lokal och global nivå.

För INT0 interruptet kan man välja mellan låg nivå, eller vid varje förändring, eller mellan positiv eller negativ flank.

EIMSK |=  ( 1 << INT0 );    // Local Enable external interrupt INT0
EICRA &= ~( 1 << ISC00 );   // INT0 on falling edge
EICRA |=  ( 1 << ISC01 );   // INT0 on falling edge
sei();                      // Global Enable interrupts

Kontaktstudsar

Trycknappen "studsar" när den sluter pinnen till jord. Den gör därför många interruptförsök varje gång man trycker på knappen. I interruptrutinen ligger därför en fördröjningsrutin för att vänta ut att kontaktstudsarna hunnit ta slut innan man återgår till huvudprogrammet och interrupt på nytt blir tillåtna.

ISR( INT0_vect )
{

    PORTB ^= ( 1 << PB5 );    // Toggle LED on pin 13 (PB5)
     _delay_ms(200);          // wait for contact bounces to settle
    EIFR  |= ( 1 << INTF0 );  // Clear INTF0 flag probably set by bounces during wait
}

Interruptflaggan blir automatiskt reset under interruptrutinen, men detta sker tyvärr innan man lämnar rutinen. Kontaktstudsarna kan hinna aktivera interruptflaggan på nytt så därför måste man resetta den som det sista man gör i rutinen.

Det fullständiga programmet finns här:


Tillbaka till startsidan

 


William Sandqvist    william@kth.se