Hallo,
wollte mal meine Entprellung vorstellen. Warum, gibt doch schon 1000?
1. damit jemand anders vielleicht noch einen Fehler sieht, denn ich
immer wieder übersehe!
wegen folgenden Vorteile:
- Ein und Ausschalten werden entprellt (sollte ja Standard sein =) )
- der C Code ist einfach gehalten
- der C Code ist ausreichend schnell (kommt natürlich auf das Programm
an)
- schon verhandener Timer-Interrupt wird "mitbenutzt"
- denoch geschiet die Entprellung im Main Loop
- sollte die Taste nach 10 Jahren abgedroschen und ausgeschlackert sein,
funktioniert die Entprellung trotzdem. Solange eine Bedingungen
erfüllt
ist: Die Abtastzeit hat mindestens die doppelte Frequenz des Prellens
Nachteile1: (klar gibts auch ;) )
- notwenigkeit eines Timer-Interrupts Zeit ca. kleiner als 1ms
sonst kann es passieren das die Abtastzeit zu klein ist
- wenn der Controller gestartet wird und der ausgeschaltene Taster eine
Funktion aufrufen soll, muss man beim Start etwas tricksen ;)
- den Entprellcode in einer Funktion auszulagern erscheint mir wenig
sinnvoll
ich benutz ihn direkt in der main loop
- man braucht 2 Byte RAM für einen Taster
So hier nun Ausschnitte aus dem Code:
1
#define E_B_Drehrichtung 0
2
#define E_B_NotAus 1
3
#define E_B_Start 2
4
#define E_B_Bremsen 3
5
6
//Taster Prellzeit ist abhänig vom Timerinterrupt
7
#define Prellzeit 20
8
9
//"sendet" steigende Flanke von Timer0 an die main...
//wenn entprellung abgeschlossen und Taster gedrückt
103
if(i_bremsen>Prellzeit&&!Brems_Taster){
104
Brems_Taster=1;
105
}
106
//wenn entprellung abgeschlossen und Taster nicht gedrückt
107
if(i_bremsen<1&&Brems_Taster){
108
Brems_Taster=0;
109
}
110
111
//Hier weitere Dinge die man jeden Xten Interrupt tun möchte,
112
// ohne Interruptzeiten zu blockieren
113
114
}
115
//Interrupts ein
116
sei();
117
}
118
return0;
119
}
Laut AVR Studio braucht die reine Tasterabfrage für 3 Taster ca 65
Cycles und dies auch nur, wenn ein Timerinterrupt ausgelöst wurde.
Das ausschalten der Interrupts kann man eventuell weglassen, da es nur
eine 8 Bit Variable ist.
Der Code lief bei mir auf einem ATMEGA32.
Ich hoffe ihr müsst nur noch die Headers einbinden und dann läuft er...
hab ihn jetzt nur rauskopiert und zusammengestückelt. So noch nicht
getestet...
Anregungen und Kritik ausdrücklich erwünscht...
Grüße
Sebastian Förster
Sebastian Förster schrieb:
> - man braucht 2 Byte RAM für einen Taster
Das ist viel.
Wie wärs mit 4 Byte für 8 Taster?
> Laut AVR Studio braucht die reine Tasterabfrage für 3 Taster ca 65> Cycles und dies auch nur, wenn ein Timerinterrupt ausgelöst wurde.
Das ist viel.
Wie wärs mit 20 Zyklen für 8 Taster?
http://www.mikrocontroller.net/articles/Entprellung#Komfortroutine_.28C_f.C3.BCr_AVR.29
Peter
Sebastian Förster schrieb:
> - den Entprellcode in einer Funktion auszulagern erscheint mir wenig> sinnvoll> ich benutz ihn direkt in der main loop
Ich finde, es macht viel Sinn, das Main möglichst übersichtlich zu
halten, d.h. allen Ballast, der nicht zum Main gehört, in Funktionen
auszulagern.
Z.B. würde sich dieser Wust:
1
>//Zuerst mit der Drehrichtung die Schütze einschalten und später
2
>//die Schalterstellung des Starttasters abfragen
3
>//ist Pin gedrückt und Prellzeit noch nicht auf maximal, dann aufaddieren
Hallo Peter,
Peter Dannegger schrieb:
> Ich finde, es macht viel Sinn, das Main möglichst übersichtlich zu> halten, d.h. allen Ballast, der nicht zum Main gehört, in Funktionen> auszulagern.
Ja, darum stand der Text unter Nachteile und ich halte auch viel davon
die main sauber zu halten ;)
Man kann das ganze schon als Funktion zusammen fassen... aber das
überlass ich jedem selbst. Der Funktion müssten 3 Parameter übergeben
werden und einen davon als Pointer und man bekommt eine returned... Ob,
dass jetzt so viel besser ist, soll jeder selbst entscheiden.
Ich hab mir übrigens deine Entprellroutine vorher auch angeguckt. Und es
ist wirklich nen sehr ausgefeilter Code und wenn ich nen Tastenfeld
hätte und sehr viel Entprellen müsste, dann würd ich den sicherlich auch
verwenden.
Ich für meinen Teil, hab aber ne einfache Lösung gesucht !ohne!
Bitoperationen auszuführen. Natürlich könnte ich auch nur ein Byte pro
Variable benutzen!!! Die ersten 5 Bit zähle ich bis 20 hoch und das MSB
sagt mir dann ob der Taster gesetzt ist...
Aber möcht ich das? Jedenfalls nicht für 3 Taster...
Außerdem kann man so, mehr als 2 Taster gleichzeitig entprellen (obs
gebrauch wird, ist ne andere Frage) und ich kann Taster entprellen die
über 40ms Prellen...
@Peter Ich hoffe ich hab deinen Code jetzt richtig interpretiert
Mir ist noch aufgefallen das man die If Abfragen besser schachteln kann
und so nochmal bis zur hälfte der Zeit sparen kann:
Sebastian Förster schrieb:
> Ich hab mir übrigens deine Entprellroutine vorher auch angeguckt. Und es> ist wirklich nen sehr ausgefeilter Code und wenn ich nen Tastenfeld> hätte und sehr viel Entprellen müsste, dann würd ich den sicherlich auch> verwenden.
Nö, der lohnt sich schon ab einer Taste. Daß nebenbei die 7 anderen Pins
mit entprellt werden, kostet nix extra.
Schau mal ins Assemblerlisting, wie wenig Code erzeugt wird.
> Ich für meinen Teil, hab aber ne einfache Lösung gesucht !ohne!> Bitoperationen auszuführen.
Nö, Bitoperation sind aus CPU-Sicht das einfachste, was es gibt.
Deshalb sind sie ja auch so schnell und effizient.
> Natürlich könnte ich auch nur ein Byte pro> Variable benutzen!!! Die ersten 5 Bit zähle ich bis 20 hoch und das MSB> sagt mir dann ob der Taster gesetzt ist...
Viel zu kompliziert.
> Außerdem kann man so, mehr als 2 Taster gleichzeitig entprellen (obs> gebrauch wird, ist ne andere Frage) und ich kann Taster entprellen die> über 40ms Prellen...
Kein Problem, die 1..8 Taster werden gleichzeitig und unabhängig
entprellt.
> @Peter Ich hoffe ich hab deinen Code jetzt richtig interpretiert
Ich glaube nicht.
Der besondere Vorteil ist, daß Tastendrücke gemerkt werden.
Mich regt das immer furchtbar auf, wenn man bei kommerziellen Geräten
immer erst warten muß, bis das Programm soweit ist, ehe man die nächste
Taste drücken darf.
Peter
Ich glaub wir reden aneinander vorbei...
Dein Code ist mit sicherheit sehr schnell... das er 8 Tasten schneller
entprellt als ich eine, stell ich auch nicht infrage.
Das der Prozessor lieber Bitzustände behandelt als Bytezustände
auszuwerten ist mir auch bewusst ;)
Ich wollte einen Entprellcode schreiben, die einfach nachvollzieh und
lesbar ist. Dabei ist es mir egal ob ich 1% der CPU Zeit beanspruche
oder 0,1%... =)
> Der besondere Vorteil ist, daß Tastendrücke gemerkt werden.> Mich regt das immer furchtbar auf, wenn man bei kommerziellen Geräten> immer erst warten muß, bis das Programm soweit ist, ehe man die nächste> Taste drücken darf.
Versteh ich jetzt nicht, erklär mal bitte genauer...
MfG
Basti
Sebastian Förster schrieb:
>> Der besondere Vorteil ist, daß Tastendrücke gemerkt werden.>> Mich regt das immer furchtbar auf, wenn man bei kommerziellen Geräten>> immer erst warten muß, bis das Programm soweit ist, ehe man die nächste>> Taste drücken darf.>> Versteh ich jetzt nicht, erklär mal bitte genauer...
Im Timerinterrupt wird das Tastenbit gesetzt beim Übergang von
Losgelassen nach Gedrückt (Flanke). Und das Main kann es später
auswerten, auch wenn Du die Taste schon wieder losgelassen hast.
Bei der Flankenerkennung im Main geht dagegen das Drücken verloren, wenn
das Main erst noch ne andere Task beenden muß.
Du bist also darauf angewiesen, daß die Mainloop immer schnell genug
durchlaufen wird. Oder der Benutzer drückt, nichts passiert und er
ärgert sich.
Peter
Sebastian Förster schrieb:
> Ich wollte einen Entprellcode schreiben, die einfach nachvollzieh und> lesbar ist.
Ob ein Code nachvollziehbar ist, liegt ganz im Auge des Betrachters.
Ich gebe zu, daß man für meinen Code etwas Verständnis von
Logikoperatoren (AND, OR, XOR, NOT) haben sollte. Ideal ist, wenn man
mal was mit TTL-ICs oder PALs selber entwickelt hat.
Der Trick ist, das Logikoperatoren immer bitweise arbeiten. D.h. man muß
sich in jedem Byte nur ein Bit (z.B. Bit 0) ansehen, um den Code zu
verstehen. Dann kann man es im AVRStudio schnell mal simulieren.
Wenn man dagegen die kompletten Bytes betrachtet, versteht man natürlich
garnichts. Sie sind ja die Summe aus allen 8 Tastenbetätigungen.
Peter
Ja stimmt, wenn natürlich die main nicht jede ms durchläuft, dann wird
ein Tasterdruck nicht so schnell erkannt.
Das ist dann wieder Geschmackssache. Ob man den Code, lieber gleich im
Timerinterrupt abarbeitet oder ob man sich sagt, dass Tasteneingabe eher
eine sekundäre Aufgabe ist, liegt dann am Programmierer.
Ja genau Peter... es ist immer ne Frage wo man her kommt... Ich hab
früher viel Anwendungssoftware in C für Windows geschrieben. Wenn ich
heute noch kleine Programm in Visual Basic schreibe, dann denk ich mir
auch: Wo ist den hier der Pointer? Wie unwirtschaftlich ist das denn?
Und wenn du aus der ASM Ecke kommst, dann siehst du das auch mit ganz
andere Augen!
Aber das soll ja jetzt keine Grundsatzdiskusion über Programmiersprachen
werden =)
Grüße
Basti
Um mal auf Deinen Code zurück zu kommen, vielleicht könntest Du mal
einen einfachen compilierbaren Code as Anhang posten, z.B. 2 Tasten und
2 LEDs, jede Taste toggled ihre LED. Dann könnte man ihn mal
ausprobieren.
Das ist ja mit dem bisherigen Code nicht möglich. Daher kann man nicht
sagen, ob er überhaupt funktioniert.
Peter