Hendrich.org

Atmega: Codebeispiel zum Interrupt abfragen

Veröffentlicht: 01.04.2011

Elegant ist es, einen Tastendruck oder das digitale Signal des Stromzählers mittels Interrupt in einen Counter auf dem Mikrocontroller zu übertragen.

Meist löst ein Flankenwechsel auf einem der Eingänge einen Interrupt aus. Man muss allerdings noch später herausfinden, auf welchem Eingang ein Flankenwechsel stattgefunden hat.

Hierzu folgender Beispielcode:

ISR (PCINT0_vect)                   // Interrupt on PCINT3 vector
{
 uint8_t changedbits;
 changedbits = (PINB ^ portbhistory);  // xor
 portbhistory = PINB;
 
 if((changedbits & (1 << PB1))>0)   // Pin1
 {
  if((PINB & (1 << PB1))>0)        // Rising edge
  {
   // Do something
  }
  else // falling edge
  {
   // Do something
  }			
 }
 if((changedbits & (1 << PB3))>0)   // Pin3
 {
  if((PINB & (1 << PB3))>0)        // Rising edge
  {
   // Do something
  }
  else // falling edge
  {
   // Do something
  }			
 }			
}

Außerdem muss noch global die Variable für die Porthistory angelegt werden:

volatile uint8_t portbhistory = 0xFF;     // default is high because the pull-up

Die Initialisierung erfolgt so, dass sowohl fallende und ansteigende Flanke detektiert werden:

#define PORT0 0
#define PORT1 1
#define PORT2 0
#define PORT3 1
#define PORT4 0
#define PORT5 0
#define PORT6 0
#define PORT7 0
#define PORT_MASK (PORT0 * 1 + PORT1 * 2 + PORT2 * 4 + PORT3 * 8 + PORT4 * 16 + PORT5 * 32 + PORT6 * 64 + PORT7 * 128)

GIMSK = (1<<PCIE);       // Pin Change Interrupt Enable
PCMSK = PORT_MASK;       // Enable external interrupts PCINT0

MCUCR = (1<<ISC00);      // PCINT0 is triggered on any change
MCUCR &= ~(1 << ISC01);  // 
sei();                   // Global enable interrupt