Hallo,
ich habe eine kleine Routine zum Entprellen eines Tastersignals geschrieben. Ich benutze das MK2 Übungsboard mit einem 2MHz µC. Der Taster ist an Port D.3 angeschlossen. An den Ports B.1 bis B.3 sind die LEDs angeschlossen, an B.0 der Tongeber, der bei jedem Schalten einmal kurz piept. Über den externen Interrupt (bei fallender Flanke) werden die LEDs umgeschaltet (quasi in Form eines kleinen Binärzählers). Beim Drücken des Tasters wird leider öfter mehrere Male geschaltet, ich kann mir aber nicht erklären, warum das so ist.
Hier die Entprellroutine:
Zur Vollständigkeit die Interrupts:Code:#define bit_3 3 . . . void entprellen() { uint8_t zustand, alterzustand; uint16_t countdown; countdown = 255; while (countdown > 0) { zustand = PIND & (1<<bit_3); // aktueller Schaltzustand (maskiert) if (alterzustand != zustand) countdown = 255; // bei Änderung zum vorherigen: Countdown von vorne else countdown--; // sonst: runterzählen alterzustand = zustand; // Schaltzustand merken } return; }
Code:ISR(INT1_vect) { entprellen(); temp = (PORTB>>1); if (++temp == 8) temp = 0; PORTB = (temp<<1); // Ton einschalten (Timer 0 Interrupt bei Überlauf aktiv) TIMSK0 = 1; } ISR(TIMER0_OVF_vect) { // aktuelles Ausgangssignal: Bits 1 bis 7 maskieren, bleiben unverändert maske = PORTB & 0b11111110; // aktuelles Ausgangssignal: Bit 0 maskieren und umkehren temp = PORTB & 1; temp ^= 1; // Ausgabe des neuen Signals PORTB = maske | temp; // Timer zurücksetzen TCNT0 = 190; // Ton unterbrechen if (++zaehler == 0) TIMSK0 = 0; }
Ich hatte das ganze vorher schon in Assembler umgesetzt. Da funktioniert das Entprellen, beim Drücken des Tasters wird genau einmal weiter geschaltet. Aber meiner Meinung sind die C- und die Assembler-Version absolut gleichwertig.
Code:entprellen: ; Register sichern push r16 push r17 push r18 ldi r16, 255 debounce: ; Zustand von PORT D einlesen und maskieren in r17, PIND andi r17, 0b00001000 ; Debounce-Zeit zurücksetzen, wenn der Schaltzustand anders ist cpse r18, r17 ldi r16, 255 mov r18, r17 ; Countdown bis 0 dec r16 brne debounce ; Register wiederherstellen pop r18 pop r17 pop r16 ret
Wer weiß Rat?







Zitieren

Lesezeichen