Forum: Mikrocontroller und Digitale Elektronik Peter Dannegers Tastenenptrellung - Modifikation Problem


von Marcel (Gast)


Lesenswert?

Moin zusammen,

ich beschäftige mich momentan wieder mit dem leidigen Thema der 
Tastenentprellung und benutze als Grundlage Peter Dannegers Code, doch 
muss ich diesen modifizieren, um ihn für meine Anwendung nutzbar zu 
machen.

Hintergrund der Modifikation ist, dass ich nicht einen Timer Overflow 
benutze, sondern einen Capture, da ich einen Atmega169 im 
Energiesparmodus betreibe. Hier ist nur noch Timer2 verfügbar (wird 
separat über den TOSC Pin getaktet). Der Overflow wird bereits durch 
eine RTC benutzt.

Soweit so gut.
Peter Dannegers Code läuft soweit ohne Probleme mit dem Capture, doch 
wird hier dauerhaft alle 10ms der Port-Eingang abegefragt.
Dies muss ich aufgrund meiner Stromsparoption ändern:

Da die 2 Taster einen PinChange auslösen, aktiviere ich im PCINT das 
Capture Interrupt - das läuft ohne Probleme. Doch muss dieses dann auch 
wieder abgeschaltet werden. Hierzu fügte ich eine zweite Variable ein, 
die einfach zählt wie oft das Capture Interrupt ausgelöst wurde. Wenn 
diese eine gewisse Zahl erreicht, so wird das Capture-Interrupt 
abgeschaltet. Das geht auch ohne Probs. :)

Doch hat einer meiner Taster (S1) eine Repeat-Funktion, sprich wenn 
diese Taste 5Sekunden lang gedrückt wird, so wird die FLAG S1_LONG 
gesetzt.

Wenn ich Taste2 (hier geht nur einfaches Drücken) betätige, so läuft die 
Modifikation, sprich das Capture-Interrupt wird gleich abgeschaltet.

Wenn ich jedoch Taste1 kurz drücke, so bleibt der Capture-Interrupt ca. 
7Sekunden an?! - Wo ist mein Fehler?
Danke im Vorraus

Hier mein Code:

> ISR(TIMER2_COMP_vect )
> {
> static uint8_t ct0, ct1,rpt, counter;
> uint8_t i;
>
> OCR2A = TCNT2 + 5; //20ms
> i = key_state ^ ( (~PINE) & FLAG_CODE_TASTER);    // key changed ?
> ct0 = ~( ct0 & i );      // reset or count ct0
> ct1 = ct0 ^ (ct1 & i);    // reset or count ct1
> i &= ct0 & ct1;      // count until roll over ?
> key_state ^= i;      // then toggle debounced state
> FLAG1_LOC |= key_state & i;    // 0->1: key press detect
>
> if( (key_state & (1<<FLAG_S1_PRESSED) ) == 0 )  // check repeat function
> {
>   rpt = 40;    // start delay
> }
>
>
> if(++counter == 5) //Interrupt wurde 5mal aufgerufen
> {
>   if( (PINE & (1<<FLAG_S1_PRESSED) ) ) //Ist Taster1 nicht gedrückt
>   {
>     TIMSK2 &= ~(1<<OCIE2A); //Stoppe Capture-Interrupt
>     counter = 0;
>   }
>
>   else //Taster1 ist gedrückt
>   {
>     OCR2A = TCNT2 + 51; //200ms - Erst wieder in 200ms abfragen, da ja
>                                   5Sekunden gedrückt sein könnte
>   }
> }
> if( --rpt == 0 )
> {
>   //rpt = REPEAT_NEXT;      // repeat delay
>   FLAG1_LOC |= (1<<FLAG_S1_LONG); //Setze Flag Taste lange gedrückt
>   TIMSK2 &= ~(1<<OCIE2A); //Stoppe Capture-Interrupt
> }
>}

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.