Hallo, ich hab ein Beispielprogrammg geschrieben (ASM) mit dem ich per Taster (an PD3 - INT1) eine LED an PB3 ein- und ausschalten kann. Läuft alles auf einem 2313. Momentan hänge ich beim Entprellen fest. Ich hab in der Codesammlung das Beispiel von Peter Dannegger gefunden. Es handelt sich um den hier: ###################################### in savesreg, sreg bst key_reg, key_state ;Bit Store from Register to T sbis key_in, key_pin ;Skip if Bit in I/O Register is Set rjmp _deb_x0 ;Sprung _deb_x0 brts _deb_11 ;Branch if T Flag is Set rjmp _deb_10 ;Sprung _deb_10 _deb_x0: brts _deb_10 ;Branch if T Flag is Set _deb_00: _deb_11: ;key_state == key_pin cbr key_reg, 0x03 ;reset debounce counter -- clear bit in register _deb_10: _deb_01: ;key_state != key_pin sbrs key_reg, key_press ;Skip if bit in register is set inc key_reg ;count up out sreg, savesreg reti ###################################### Leider will sich mir der Sinn des Codes nicht erschliessen :-( ! Kann mir das jemand erklären? Das ganze wird ja abgearbeitet sobald der T0 Interrupt auftritt. Das sichern der Statusregister ist mir auch noch klar... :-). Leider fehlen mir jedoch schon die Deklarationen für key_reg, key_state, key_in, key_pin, key_press. Ich bedanke mich schon mal für eure Bemühungen. Gruss, Markus
Das hat Peter aber in der Codesammlung erklärt, in dem Beitrag, in dem er den Code veröffentlicht hat. Es ist nicht leicht zu verstehen, ich habe auch etwas gebraucht. Das Verhalten der beiden Zählregister ist mir noch nicht hundertprozentig klar, aber sie zählen halt... Ansonsten ist es die beste Tastenentprellung (betreffs Aufwand und Nutzen), die ich je gesehen habe. Ich nutze sie inzwischen auch. ...
Achja, schieb's mal durch den Simulator und schau den Registern auf die Bits, vergleiche dabei das, was du erwartest mit dem, was passiert. Vielleicht helfen dir ja die Kommentare in meiner Version: ;----- .def scan=r5 ;Scannwert Tastenport .def tz0=r6 ;Tasten-Prellzähler Bit0 .def tz1=r7 ;Tasten-Prellzähler Bit1 .def tas=r8 ;Tastenstatus (gültig) .def tfl=r19 ;Flags für Tasten, die gedrückt wurden ;und in der ISR: Tastenabfrage: ;Entprellroutine geklaut bei Peter Dannegger... in scan,tap ;Tastenport einlesen (gedrückt=H) com scan ;invertieren (gedrückt=L) eor scan,tas ;nur Änderungen werden H and tz0,scan ;Prellzähler unveränderter Tasten löschen (Bit0) and tz1,scan ;Prellzähler unveränderter Tasten löschen (Bit1) com tz0 ;L-Bit zählen 0,2,->1, 1,3,->0 eor tz1,tz0 ;H-Bit zählen 0,2,->tz1 toggeln and scan,tz0 ;Änderungen nur dann erhalten, wenn im Prellzähler and scan,tz1 ;beide Bits gesetzt sind (Zählerstand 3) eor tas,scan ;erhaltene Änderungen toggeln alten (gültigen) ;Tastenstatus and scan,tas ;nur (neu) gedrückte Tastenbits bleiben erhalten or tfl,scan ;und zugehörige Bits setzen (gelöscht wird nach ;Abarbeitung) ;in "tas" steht jetzt der gültige Tastenzustand, ;in "tfl" die Flags der neu gedrückten, noch nicht abgearbeiteten ;Tasten... ;----- Selbstverständlichkeiten, wie SREG-Sicherung, Timer-Reload usw. wurden bewusst weggelassen. Das Programm läuft im Timer0-Interrupt, der alle 10ms auftritt (also alle 10000 Takte). ...
Da hat natürlich wieder mal der Logikteufel zugeschlagen. Ist genau umgekehrt: in scan,tap ;Tastenport einlesen (gedrückt=L) com scan ;invertieren (gedrückt=H) ...
Hi, danke für deine Erklärungen, ich werd mir das heut abend zu Gemüte führen. Es bringt mich aber bestimmt weiter. Gruss, Markus
@Markus, ich habe den Eindruck, daß Hannes eine völlig andere Routine meint. War aber auch zu erwarten, wenn man keine URL angibt, worauf man sich bezieht und der andere nicht Gedanken lesen kann. Ich kann jedenfalls nicht wissen, wo ich mal was geschrieben habe, dazu sind es einfach zu viele Beiträge (>1000). Peter
Stimmt... Da war ich wohl zu voreilig und habe den Programmcode überlesen (key_state... kenn ich doch, das ist doch... - Isses aber doch nicht...) Sorry, da werde ich wohl demnächst besser aufpassen müssen... Aber ich werde mir die Quelle der obigen Routine mal suchen und versuchen diesen Code zu verstehen, jetzt auf Anhieb gelingt mir das auch nicht... ...HanneS... (der sich jetzt schämt...)
Hi... Um die Routine zu verstehen, muss man sich erstmal das Register key_reg und seine Bits genauer ansehen: key_reg ist ein oberes Register, von dem nur das untere Nibble für die Tastenentprellung genutzt wird. Das obere Nibble kann für andere "Flags" im Programm benutzt werden. Die benutzten Bits in key_reg: 0 Prellzähler, unteres Bit, 1 Prellzähler, oberes Bit, wird bei Tastenänderung hochgezählt und bei Gleichheit mit dem alten Tastenzustand gelöscht. Daher werden Änderungen nur übernommen, wenn diese 4 mal direkt hintereinander (also bei Überlauf in Bit 2) auftreten. 2 key_state, (gültiger) Tastenstatus, wird durch Überlauf des Prellzählers getoggelt, also nur wenn der Taster 4 Runden lang stabil dem entgegengesetzten Zustand von key_state entspricht. L bedeutet gedrückte Taste. 3 key_press, ein Flag, das anzeigt, dass der Taster gedrückt wurde. Wird durch Überlauf von Bit 2 (key_state) gesetzt, wenn dieses durch Hochzählen des Prellzählers von H nach L toggelt und durch das Hauptprogramm beim Abarbeitung des Tastendruckereignisses wieder gelöscht. Dann habe ich versucht, die Routine verständlich zu kommentieren: _timer0_ovf: ;Interrupt-Service-Routine Timer0-Überlauf in savesreg, sreg ;SREG sichern (Exclusiv-Register) bst key_reg, key_state ;alten (gültigen) Tastenzustand ;zum Vergleichen ins T-Flag, dabei ;ist L=gedrückte Taste sbis key_in, key_pin ;Ist die Taste gedrückt? ;überspringe, wenn nicht rjmp _deb_x0 ;ja, Taste ist gedrückt (L), weg hier _deb_x1 ;Debounce bei unbetätigter Taste (1, H) brts _deb_11 ;(Taste ist H) Taste gleich T-Flag?? ;springe weg, wenn ja, also wenn ;keine Änderung auftrat rjmp _deb_10 ;Änderung aufgetreten, weg hier... _deb_x0: ;Debounce bei gedrückter Taste (0, L) brts _deb_10 ;(Taste ist L) Taste gleich T-Flag?? ;springe weg, wenn nicht, also wenn ;eine Änderung auftrat _deb_00: ;Debounce alter Wert=0, neuer Wert=0 (Gleichheit) _deb_11: ;Debounce alter Wert=1, neuer Wert=1 (Gleichheit) ;key_state == key_pin (also keine Änderung) cbr key_reg, 0x03 ;Prellzähler löschen (Bit 0 und 1) ;reset debounce counter (dasselbe...) _deb_10: ;Debounce alt=1, neu=0 (Ungleichheit, Änderung) _deb_01: ;Debounce alt=0, neu=1 (Ungleichheit, Änderung) ;key_state != key_pin (also Änderung) sbrs key_reg, key_press ;Tastenflag gesetzt? (also gültigen ;Tastendruck noch nicht vom Hauptprogramm ;"abgeholt") - überspringe, damit der ;Prellzähler bis zum Abarbeiten und ;Quittieren vom Hauptprogramm angehalten ;wird inc key_reg ;Prellzähler erhöhen out sreg, savesreg ;SREG wiederherstellen reti ;fertig... Betrachtet man das untere Nibble des key_reg als einen 4-Bit-Zähler (0...15) dann kann man den Ablauf so sehen: 0: Tastenflag abgeholt (Bit3=0), Tastenstatus = gedrückt (Bit2=0), Prellzähler=0... 1: Tastenflag abgeholt (Bit3=0), Tastenstatus = gedrückt (Bit2=0), Prellzähler=1... 2: Tastenflag abgeholt (Bit3=0), Tastenstatus = gedrückt (Bit2=0), Prellzähler=2... 3: Tastenflag abgeholt (Bit3=0), Tastenstatus = gedrückt (Bit2=0), Prellzähler=3... 4: Tastenflag nicht gesetzt (Bit3=0), Tastenstatus = nicht gedrückt (Bit2=1), Prellzähler=0... 5: Tastenflag nicht gesetzt (Bit3=0), Tastenstatus = nicht gedrückt (Bit2=1), Prellzähler=1... 6: Tastenflag nicht gesetzt (Bit3=0), Tastenstatus = nicht gedrückt (Bit2=1), Prellzähler=2... 7: Tastenflag nicht gesetzt (Bit3=0), Tastenstatus = nicht gedrückt (Bit2=1), Prellzähler=3... 8: Tastenflag gesetzt (Bit3=1), Tastenstatus = gedrückt (Bit2=0) Prellzähler=0 Prellzähler ist gesperrt, bis Tastenflag vom Hauptprogramm gelöscht wird, was Zählerstand 0 entspricht... Entspricht dabei die tatsächliche Tastenstellung dem gespeicherten Tastenstatus, so werden Bit0 und Bit1 gelöscht, wodurch der Zähler auf Zählerstand 0 oder 4 zurückfällt und am Weiterzählen gehindert wird. Der Taster muss also 4 Abfragen hintereinander stabil auf dem Gegenpegel liegen, damit seine Änderung übernommen wird. Korregiert mich, falls ich Blödsinn geschrieben habe... ...HanneS...
Hallo, ich bin Neuling im Programmieren, habe vor ca. 14 Tagen damit angefangen. Ich habe da eine Frage zu den Interuppts. Ich verwende für eine RGB-Steuerung die Timer für die PWM, kann ich da noch per Interuppt ( Timer0 Überlauf z.B. ) eine Tastenabfrage realisieren? mein Code für die PWM: ; *** Timer Initialisieren *** ldi r16, 0xC3 out TCCR0A, r16 ; TCCR0A init., fast PWM auf OC0A (R) ldi r16, 0x03 ; Vorteiler 1/64 out TCCR0B, r16 ldi r16, 0xF1 out TCCR1A, r16 ; TCCR1A init., fast PWM auf OC1A/OC1B (G,B) ldi r16, 0x0B ; Vorteiler 1/64 out TCCR1B, r16 Ist es damit noch möglich eine Tastenabfrage per Interrupt zu erstellen? mfg Jörg
@mitchell, Hijacking eines Thread macht man nicht. Stelle bitte Deine Frage vorne im Forum ! Sonst kann es sein das sie unter geht.
Stephan Henning wrote: > @mitchell, > > Hijacking eines Thread macht man nicht. > Stelle bitte Deine Frage vorne im Forum ! > Sonst kann es sein das sie unter geht. Daran bin ich wohl schuld. Ich gab ihm in einem anderen Thread den Link auf diesen Thread, da hier seine vorige Frage beantwortet wurde. --- Einen Überlauf-Interrupt sollte man eigentlich immer unterbringen können. Alternativ sollte man sich überlegen, ob LEDs wirklich Hardware-PWM brauchen. Software-PWM sollte für LEDs eigentlich ausreichend schnell sein. ...
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.