Hallo zusammen, ich habe mir zum Test ein Board auf Lochraster aufgebaut, auf dem sich zum Einlesen von 16 Tastern zwei 74HC165 befinden und zur Ausgabe auf 16 Leds zwei 74HC595. Zur seriellen Ansteuerung benutze ich einen ATTiny2313. Die Daten bekomme ich auch seriell eingelesen, und im SRAM abgelegt.Die Ausgabe der 2 Bytes funktioniert auch, zumindest soweit, dass ich sobald ich die Daten einlese und daraufhin gleich wieder an die Led`s ausgebe die jeweils zugehörige Led an geht und wenn ich sie loslasse wieder ausgeht. Jetzt zum Problem: Ich möchte die Tasten die an das Schieberegister angeschlossen sind entprellen. Anschließend soll nur bei Änderung der Tasten eine Aktualisierung der Ausgabe erfolgen. Der vorherige Schaltvorgang soll allerdings erhalten bleiben. Sprich die Tasten sollen die jeweils zugehörige Led einschalten und beim folgenden Tastendruck ausschalten. Dazu hatte ich mir die 8-Bit Entprellroutine von Peter Dannegger im Tutorial angesehen, aber leider nicht 100%ig verstanden. In meinem Code lasse ich im Hauptprogramm die Seriellen eingangsdaten jeweils in einem 2Byte grossen SRAM bereich mit dem Namen "outdaten" ablegen. Im nächsten Schritt sollen die Eingangsdaten dann mit den letzten daten jeweils Byteweise überprüft werden, und nur bei Änderung verändert im SRAM unter outdaten_old abgelegt und anschließend ausgegeben werden. Ich muss leider zugeben, dass ich gerade daran scheitere, dass ich die Daten nicht so logisch miteinander verknüpft bekomme, dass ich die alten Tastenzustände beibehalte und nur nach erneutem drücken toggeln kann. Mit einem XOR der neuen tastenflags mit den alten, bekomme ich die Anzeige, dass sich was geändert hat..hat sich nichts geändert hole ich mir das nächste Byte zur Überprüfung.Hat sich der Zustand geändert lasse ich die Tasten erneut nach Ablauf eines 16-Bit Zählers abfragen. Mit einem CP vergleiche ich dann den letzten erkannten Wechsel mit dem derzeitigen. Ist er immer noch gleich soll dann das Byte im SRAM gesichert und ausgegeben werden. Aber da hängt es irgendwie!! Gibts da irgendwo HILFE?? Vielen dank schonmal für Eure Antworten.. Lg Thomas
Die (ASM-)Entprellroutine von PeDa nutzt außer einem temporären Register 4 weitere Register exklusiv. Dies sind zwei Prellzähler und die Register, die Peter "Key_state" und "Key_press" nennt. Die Routine entprellt 8 Bit zugleich (für 16 Bit müsste sie zweimal mit verschiedenen Registern implementiert werden oder die Werte zwischendurch ins RAM auslagern) und liefert Zustand und Flanke. In Key_state steht der Tastenzustand, der interressiert aber nur, falls man so etwas wie Shift-Tasten implementieren will. In Key_press wird ein Bit gesetzt, wenn eine Taste losgelassen und erneut gedrückt wurde (Flankenerkennung). Dieses Register ist für Deinen Zweck nutzbar. Um den LED-Port zu schalten, muss er nur mit Key_press exor vernüpft werden, danach ist Kex_press zu löschen. Für den Fall, dass die Werte in Registern gehalten werden, sieht das so aus: eor leds1,key_press1 ;erste 8 LEDs gemäß Taster-Flanken toggeln clr key_press1 ;Tastenflags entwerten, haben Job ja erledigt eor leds1,key_press2 ;zweite 8 LEDs gemäß Taster-Flanken toggeln clr key_press2 ;Tastenflags entwerten, haben Job ja erledigt Solltest Du die Werte im SRAM halten, dann kommen natürlich noch die entsprechenden LDS/STS (oder LD/ST über Pointer) dazu, die die Routine dann etwas aufblähen. ...
Hallo Hannes, vielen Dank erstmal für deine schnelle Antwort. Die Entprellung selbst wollte ich in meinem Projekt, ohne den TIMER0 Overflow sprich ohne Interrupt lösen, da die E/A-zeit der Shift- eingangs und -Ausgangsregister relativ hohe Laufzeiten haben, und ich im späteren Programmablauf die Daten seriell an eine Gegenstelle auslagern möchte. Die serielle Übertragung hatte ich aber weitgehend aus dem Programmcode gelöscht, da sie für das jetzige Problem nicht relevant war. Das Entprellen per 16-Bit zähler sollte an dieser Stelle denke ich aber auch funktionieren, oder? Zunächst wollte ich jetzt ungeachtet dessen, dass ich eigentlich 16 Bit (später mehr) zu verarbeiten habe, ein Byte prüfen, und die Leds am Ausgang ein und ausschalten. Und genau da ist das Problem, denn ich bekomme die beiden Daten (outdaten_old), die ja immer den aktuellen Zustand der Leds haben, nicht mit den entprellten (Outdaten) verknüpft, so dass der alte zustand erhalten bleibt, und nur die "gedrückte Taste" getoggelt wird. Habe ich z.b. Outdaten_old mit 11110111 (derzeitiger Zustand der Leds) und bei Tastendruck Outdaten mit 11011111 (nach der Entprellung) komme ich nicht auf die Lösung, wie ich das (alte) gesetzte bit in Outdaten_old beibehalten kann und logisch mit den neuen (aktuellen Tastendrücken) verknüpfen muss um im Beispiel die 11010111 zu erhalten. Der jetzige Code gibt mir jeden Tastendruck bei änderung entprellt weiter, und gibt ihn bei Änderung an die Leds aus. Jedoch löscht er die leds nach dem Loslassen auch wieder. Den gesamten Code habe ich angehangen.. Viele Grüße Thomas
Hi Dein Problem ist, das du auf Drücken und Loslassen reagierst. Wenn du nur auf das Drücken reagieren willst ist eine zusätzliche Verknüpfung notwendig. Allerdings ist es notwendig, das eine gedrückte Taste durch H representiert wird. Mit: eor alter Wert,neuer Wert and alter Wert,neuer Wert steht in 'alter wert' nur dort ein H wo eine Taste neu gedrückt wurde. Damit lassen sich z.B. die LEDs umschalten: eor led,alter Wert Die Werte für die Tasten und die LEDs würde ich in getrennten Werten speichern. MfG Spess
> Dein Problem ist, das du auf Drücken und Loslassen reagierst.
Dann ist es aber nicht die Dannegger-Entprellung... ;-(
Ich bezog mich auf diesen Algorithmus, wobei ich allerdings meine
eigenen Variablennamen benutze:
1 | entprellung: ; |
2 | cbr flags,1<<entprell ;Jobflag löschen |
3 | Tastenabfrage: ;Entprellroutine (Algorithmus geklaut bei Peter Dannegger...) |
4 | in temp,tap ;Tastenport einlesen (gedrückt=L) |
5 | com temp ;invertieren (gedrückt=H) |
6 | eor temp,tas ;nur Änderungen werden H |
7 | and tz0,temp ;Prellzähler unveränderter Tasten löschen (Bit0) |
8 | and tz1,temp ;Prellzähler unveränderter Tasten löschen (Bit1) |
9 | com tz0 ;L-Bit zählen 0,2,->1, 1,3,->0 |
10 | eor tz1,tz0 ;H-Bit zählen 0,2,->tz1 toggeln |
11 | and temp,tz0 ;Änderungen nur dann erhalten, wenn im Prellzähler |
12 | and temp,tz1 ;beide Bits gesetzt sind (Zählerstand 3) |
13 | eor tas,temp ;erhaltene Änderungen toggeln alten (gültigen) Tastenstatus |
14 | and temp,tas ;nur (neu) gedrückte Tastenbits bleiben erhalten |
15 | or tfl,temp ;und zugehörige Bits setzen (gelöscht wird nach Abarbeitung) |
16 | ;tmp ist wieder frei, tas enthält den entprellten Tastenstatus, |
17 | ;tfl die neu gerückten Tasten |
18 | Tastendauer: |
19 | mov temp,tas ;Tastenzustand kopieren |
20 | andi temp,reptast ;nur Tasten mit Wiederholfunktion stehen lassen |
21 | tst temp ;ist eine Taste betätigt? |
22 | breq Tastendauer0 ;nein, Dauer auf Startwert... |
23 | dec twz ;ja, Zähler runter |
24 | brne Tastenabfrage_e ;Dauer abgelaufen? - nein... |
25 | or tfl,temp ;ja, noch aktive Tasten übernehmen |
26 | ldi twz,twz1 ;und Zähler auf Wiederholwert setzen |
27 | Tastenabfrage_e: |
28 | ;in "tfl" stehen jetzt wieder die Flags der länger betätigten Tasten |
29 | ;sie werden nach Abarbeitung gelöscht |
30 | dec blto ;runterzählen |
31 | brne backlight1 ;schon unten? - nein... |
32 | cbi blp,blb ;ja, Backlight ausschalten |
33 | backlight1: |
34 | rjmp lcd_busywait_e ;fertig, zurück... |
35 | Tastendauer0: ;Reset Dauerzähler |
36 | ldi twz,twz0 ;Tastendauerzähler auf Startwert |
37 | rjmp Tastenabfrage_e ;fertig... |
Relevant ist hierbei das Register "tfl" (Tastenflags). ...
Wenn ich dein Beispiel so durchgehe: old 0b11110111 ;Bit3 war der alte zustand (Led an) neu 0b11111101 ;Bit1 ist nun neu geändert eor alt,neu 0b00001010 nach dem eor ist alt ja dann geändert.. and alt,neu 0b00001000 eor leds,alt 0b11110101 Jetzt mal umgekehrt (wiederausschalten) old 0b11110101 neu 0b11110111 eor alt,neu 0b00000010 and alt,neu 0b00000010 eor leds,alt 0b11110101 ??????????? Wenn ich das so richtig interpretiere, dann funktioniert das nicht, oder mache ich einen Fehler? LG Thomas
Was willst Du eigentlich immere mit OLD und NEU? Ich brauche dazu nur den LED-Status (dessen Kopie dann an die Schieberegister ausgeschoben wird) und die entprellten Tastenflags:
1 | ;Bit 76543210 |
2 | ;LED_Staus 0b00001111 |
3 | ;tfl 0b00100010 |
4 | eor led_status,tfl ;0b00101101 |
5 | clr tfl |
Es wurde also Bit 1 ausgeschaltet und Bit 5 eingeschaltet. Damit das nur einmal geschieht, muss tfl (Key_press bei PeDa) anschließend entwertet, also gelöscht werden. Nur ein erneuter Tastenzyklus setzt wieder ein Bit in tfl. ...
Hallo Hannes, vielen Dank für den letzten Beitrag, der war der Schlüssel zum Erfolg. Habs jetzt soweit!! Noch nen schönen Sonntag.. Lg Thomas
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.