Forum: Mikrocontroller und Digitale Elektronik Interrupt durch AVR_INT0


von Name N. (mar75)


Lesenswert?

Hallo Leute,

habe kleines C-programm geschrieben, wo ich INT0 durch ein 
Taster-Drücken auslöse. Dann wird ein Zähler um 1 erhöht.

Leider funktioniert es nicht immer, da manchmal um mehr als eins erhöht 
wird:

Bsp: Counter = 10 >> taster Drücken >> counter = 12 (Sollte aber 11 
sein)

hier ein Code-Asuschnitt:


volatile uint8_t   counter;

SIGNAL(SIG_INTERRUPT0)
{
 counter = counter + 1;
}


int main(void)
{
      PORTD = 0x0C;
      DDRD  = 0x32;
  GIFR  |= (1 << INTF0);
  GIFR  |= (1 << INTF1);
      MCUCR |= 0x03;
  MCUCR |= 0x0C;
      GICR  |= (1 << INT0);
  GICR  |= (1 << INT1);
  cli();    // clear Interrupt
  sei();    // enable interrupts

  while (1)
  { }
}


Kann mir bitte jemand dabei helfen? Vielen Dank im Voraus

Gruß

von Uwe .. (uwegw)


Lesenswert?

Stichwort: Tastenentprellung !!!

von Joan P. (joan)


Lesenswert?

^^ wenn du noch nen Timer übrig hast, kannste den ja so einstellen, dass 
der nen Output Compare Interrupt auslöst.
Dann ermöglicht dein Tastendruck den Timer-OCM-Interrupt und wenn der 
dann kommt, wird erst geschaut, wo der Taster gerade ist.. also nachdem 
er sich beruhigt hat.

zB für nen 8Bit-Timer (Zeiangaben für fCPUI/O = 8MHz):
1
// initialize irgendwo vor main{}:
2
// 8Bit - Timer: CTC-Mode(4), TOP = 0xFF, Prescaler 1/1024 (32ms bis TOP), nix externes, OCM-Interrupt
3
TCCRnA = ...
4
TCCRnB = ...
5
6
// deine Interrupt Routine
7
SIGNAL(SIG_INTERRUPT0)
8
{
9
    TCNT3 = 0x00; // Timer Zählregister reset
10
    OCRnA = 0x4F; // ca 10ms bis Timer Compare Match A Interrupt
11
    TIFRn |= (1<<OCFnA); // Timer Compare Match A Flag löschen
12
    TIMSKn |= (1<<OCIEnA); // Timer Compare Match A Interrupt aktivieren
13
} 
14
15
// Timer Compare Match A Interrupt
16
ISR (TIMERn_COMPA_vect)
17
{
18
    TIMSKn &= ~(1<<OCIEnA); // Timer Compare Match A Interrupt deaktivieren
19
    TIFRn |= (1<<OCFnA); // Timer Compare Match A Flag löschen
20
    if (<<Pin_INT0>> == <<LOW>>) // nur wenn <<Pin_INT0>> low ist, zählen ... die genauen Bezeichnungen musst du ergänzen ;-) 
21
    {
22
        counter = counter + 1;
23
    }
24
}
25
26
int main(void)
27
{
28
    PORTD = 0x0C;
29
    DDRD  = 0x32;
30
    GIFR  |= (1 << INTF0)|(1 << INTF1);
31
    MCUCR |= 0x03|0x0C;
32
    GICR  |= (1 << INT0)|(1 << INT1);
33
    sei(); // enable interrupts
34
    while (1) // loop forever
35
    { }
36
}

von Name N. (mar75)


Lesenswert?

Vielen Dank, Es funktioniert.

Grüße

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.