Hey, ich programmiere einen Atmega32. Jetzt bin ich am Überlegen, ob ich die Taster soft- oder hardwaremäßig entprelle. Software ist ja eigtl Standard heute, allerdings habe ich das Problem, dass ich den Timer1 dazu brauche, einen Takt im niedrigen Hz Bereich zu erzeugen. Die Frage nun, kann man den Timer, den man fürs Entprellen nutzt auch anderweitig noch nutzen? Grüße Joe
Ja. In der Timer-ISR kannst du neben der Debounce-State-Machine noch andere Aufgaben erledigen. Der Tastendruck sollte allerdings ein vielfaches des Timer-Taktes dauern, du wirst sonst den Tast-Event verpassen, wenn du einen niedrigen Takt einstellst (Nyquist-Shannon-Abtasttheorem).
Hey Joe, der Timer triggert eine Interruptroutine, die Du programmierst. Was Du in dieser anstellst (entprellen, weitere periodische Aktionen) ist ganz Dir überlassen. In meinen bescheidenen Projekten bislang musste ich den Timer immer nochmal softwaremäßig herunter teilen, d.h. nur bei jedem x. Aufruf des Interrupts werden langsam laufende Vorgänge erledigt (z.B. die klassische langsam blinkende LED ein- und ausgeschaltet), hierfür läuft softwaremäßig ein Zähler mit. Wenn Du fürs Entprellen häufiger pollen musst, dann ist der Code hierfür an der Stelle der Interruptprozedur unterzubringen, die mit höherer Frequenz ausgeführt wird. Gruss, Stefan
Hi Abgesehen davon, das es fertige Routinen dafür gibt, baue ich mir meine Debounce auch meist selbst.... Hier mal (m)ein Weg grob beschrieben: Port einlesen und ablegen in New_In Exclusiv-Oder mitvorherigem Wert in Deb_In Ergebnis 0 = keine Änderung wenn mSek_Flag = 1 Zählwert decrementieren msek-Flag =0 Zähler = 0 Eingänge stabil für Programm gültig nach In_Ok übergeben Ergebnis nicht "0" Zählwert hochsetzen ( 10 ... 20) neuen Wert nach alten Wert übertragen (Deb_In = New_In In der Timer-ISR setzt du ein Bit in einer Variablen (mSek_Flag) So in etwas läuft es schnell und stabil genug, um Tasten zu erfassen. Der obere Teil wird in der Programmschleife gepollt. gruß oldmax
Hallo Joe ich arbeiete mit einem Atmega 128 und 16M. Zur Steuerung verwende ich einen Timer mit 10ms. Dieser steurt die gesamte Tastenentprellung und Auswahl der Tasten (nach Peter Da.). Weiterhin verwende ich den Timer als Basis für das gesamte Programm. Suche mal den Artikel "Warten verboten". Diesen habe ich als Grund genommen. Dadurch kann ich viele Dinge (fast) gleichzeitig ausführen. Gleichzetiges steuern von LED, Laufschrift, Menue, Auswetung kurz-lang und anderes. Dabei verwende ich keinerlei delay. Zu anfang hatte ich sehr grosse Probleme. Doch mit jedem Teil geht es besser. Kann ich nur empfehlen. achim
Hey, vielen Dank für eure Antworten. Dann werde ich auf die SW Entprellung setzen und die HW Entprellung weglassen. Ich hatte eben nur "Angst", bei 3 Timern, die der Atmega32 besitzt, einen "nur" fürs Entprellen zu nutzen. Der fehlt mir wenns schlecht geht am Ende an anderer Stelle. Grüße Joe PS: Die Taster schließ ich dann gegen GND, ohne Vorwiderstand, mit aktiviertem Pull up, richtig?
Hi Richtig. Übrigends, diese Angst haben viele, das der Timer nicht mehrere Dinge abarbeiten kann. Denk einfach mal an eine Uhr. Da schauen auch viele Eute drauf und erledigen entsprechend verschiedene Arbeiten, obwohl es auch nur eine Uhr ist.Ich richte mir meinen Timer so ein, das er in jeder mSek. aufgerufen wird. Je nach Bedarf werden Zeiten erfasst (durch zählen halt) und dann Bits in einer Variablen abgelegt. Das Programm prüft die Bits und erledigt entsprechend den Job, wenn eines gesetzt ist. dann wird das Bit nach der Bearbeitung gelöscht. In Assembler sieht das in etwa so aus:
1 | Time_Flags: .Byte 1 ; Zeitereignisse |
2 | ; Bit 0 = 1 mSek |
3 | ; Bit 1 = 50 mSek |
4 | ; Bit 2 = 0,2 Sek |
5 | ; Bit 3 = 0,5 Sek |
6 | ; Bit 4 = 1 Sek |
7 | ; Bit 5 = 10 Sek |
8 | ; Bit 6 = 1 Minute |
9 | ; Bit 7 = 1 Stunde |
10 | .... |
11 | |
12 | Loop: |
13 | .... |
14 | LDS R16, Time_Flags |
15 | MOV R1,R16 |
16 | ANDI R16,0b00000001 |
17 | BREQ fuenfzig |
18 | RCALL One_Milli |
19 | Fuenfzig: |
20 | Mov R16, R1 |
21 | ANDI R16, 0b00000010 |
22 | BREQ Komma_Zwei |
23 | RCALL Fuenfzig_Milli |
24 | Komma_Zwei: |
25 | .... |
26 | |
27 | |
28 | JMP Loop |
29 | |
30 | One_Milli: ; Zeitereignisbearbeitung jede Millisekunde |
31 | ..... |
32 | ..... |
33 | Mov R16, R1 |
34 | ANDI R16, 0b11111110 |
35 | STS Time_Flags, R16 ; Flag quittieren |
36 | RET |
37 | |
38 | Fuenfzig_Milli: ; Zeitereignisbearbeitung alle 50 Millisekunden |
39 | ..... |
40 | ..... |
41 | Mov R16, R1 |
42 | ANDI R16, 0b11111101 STS Time_Flags, R16 ; Flag quittieren |
43 | RET |
So habe ich für jeden Bedarf Zeitereignisse. Klar, das die Programmteile im mSek.Bereich nicht allzugroß ausfallen dürfen. gruß oldmax
Joe B. schrieb: > allerdings habe ich das Problem, > dass ich den Timer1 dazu brauche, einen Takt im niedrigen Hz Bereich zu > erzeugen. T1 hat ja OCR1A und OCR1B. Mit dem einen Register erzeugst Du Deine niedrige Frequenz (großer Wert) und das andere Register wird auf einen kleineren Wert gesetzt (höhere Frequenz). Beim Compare-Ereignis werden die Register jeweils um diesen (Nachlade-)Wert erhöht. Damit erzeugt man Interrupts mit konstanten Abständen. T1 darf aber weder von OCR1A oder OCR1B gelöscht/zurückgesetzt werden!
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.