Forum: Mikrocontroller und Digitale Elektronik Softwaremäßige Entprellung


von Joe S. (bubblejoe)


Lesenswert?

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

von WaddeHaddeDuDeDa (Gast)


Lesenswert?

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).

von Stefan K. (stefan1971)


Lesenswert?

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

von oldmax (Gast)


Lesenswert?

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

von Achim S. (achims)


Lesenswert?

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

von Joe S. (bubblejoe)


Lesenswert?

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?

von oldmax (Gast)


Lesenswert?

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

von Willi (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.