Hi,
ich möchte ein Tastendruck, was länger als 1 sec dauert, erkennen und
danach einen Parameter ändern.
Folgendes:
1. ich prüfe ob eine Taste gedrückt wurde
2. wenn Taste gedrückt wurde, wegen Prellung warte ich 100usec und prüfe
noch mal den Tastendruck
3. ist die Taste nach immer noch gedrückt, warte ich 1sec lang
4. nach 1sec schaue ich, ob immer noch die Taste gedrückt ist
5. ist nach 1 sec immer noch die Taste gedrückt, wird der Parameter
geändert
Ist das eine gute Lösung? Bitte sagt mir, wie ihr es besser machen
würdet
Vielen Dank
1
boolA1_value=0;
2
3
A1_value=A1_GetVal();//Wert am Port A1 abfragen
4
if(A1_value)//wenn die Taste gedrückt ist A1_value->TRUE
5
{
6
Cpu_Delay100US(1);//wegen Entprellung 100us delay
7
8
A1_value&=A1_GetVal();//Wert am Port A1 mit altem Wert UND-Verknüpfen
9
10
if(A1_value)// Taste gedrückt ->TRUE, sont FALSE
11
{
12
Cpu_Delay100US(10);//1sec warten und noch mal Wert am Port A1 abfragen
13
A2_value&=A1_GetVal();
14
15
if(A1_value)//wenn nach 1sec immer noch gedrückt A1_value->TRUE, sonst FALSE
Nun, sowas ist keine Entprellung. zumal 100µs doch sehr kurz ist.
Mache das am Besten in einem Timerinterrupt nach folgendem Ablauf:
(pseudocode)
Timerinterrupt alle zB 1ms.
{
if (Taste nicht gedrückt)
{
Zähler = 0;
}
else
{
Zähler = Zähler + 1;
}
if (Zähler > 100)
{
Taste_gedrückt = 1;
Zähler = Zahler - 30;
}
}
--------------
main
{
..
if ( Taste_gedrückt = 1 )
{
Taste_gedrückt = 0;
.. mach was..
}
..
}
Die Taste muss 100ms gedrückt sein, dann wird das mit dem Flag
"Taste_gedrückt" gespeichert. Wird die Taste weeiterhin gedrückt
gehalten, dann wird das alle 30ms wieder erkannt (repeat-funktion)
Das hauptprogramm muss natürlich schneller als diese 100ms sein, und
kann dann drauf reagieren...
ja natürlich kann er in der Zeit nichts machen, weil es ja entprellt
werden muss. Wie soll es sonst gehen?
wenn ich andere Lösung hätte, würde ich eher sagen dass
"Cpu_Delay100US(10); //1sec warten und noch mal Wert am Port A1
abfragen" Mist ist. Aber ich kenne keine bessere Lösung, daher bitte ich
euch um Hilfe
>ja natürlich kann er in der Zeit nichts machen, weil es ja entprellt>werden muss. Wie soll es sonst gehen?
Siehe Beitrag von Lippy von 16:53.
Das Zauberwort heisst Interrupt
Dafür gibt es auch ein nettes Kapitel im GCC-Tutorial
>Nun, sowas ist keine Entprellung. zumal 100µs doch sehr kurz ist.>Mache das am Besten in einem Timerinterrupt nach folgendem Ablauf:
und wenn ich den Tastendruck NUR am Ende vom Programm abfrage, damit
bevor es wieder zum Anfang sprint, ich weiss welcher Modus aktiviert
werden soll?
Mach das ordentlich, sonst wird das nie richtig funktionieren.
Es sei denn, du willst nach der Trial&Error Methode die
Wollknäulprogrammierung betreiben..
>Das Zauberwort heisst Interrupt>Dafür gibt es auch ein nettes Kapitel im GCC-Tutorial
ein Interrupt kann ich nicht einsetzten, weil ich nicht Mitten im
Programm in die ISR springe will und den Parameter ändere, was aber im
Laufe des Programms ständig geändert wird.
D.h. den Tastendruck kann ich nur am Ende vom Programm abfragen, damit
der richtige Modus eingstellt wird, wenn die Taste gedrückt ist.
> ISR springe will und den Parameter ändere
Lies richtig! Im ISR wird auch nur der Tastendruck ausgewertet und
gemerkt.
Wenn du unsere Tipps nict willst, dann erhöhe einfach das delay auf eine
Sekunde und fertig.
Das ist zwar gebastel, aber was solls...
wenn du den Code anschaust, ist auch eine 1sec delay enthalten. Aber wo
ich jetzt
>Im ISR wird auch nur der Tastendruck ausgewertet und gemerkt
gelesen habe, ist mir was anderes eingefallen.
wenn Taste gedrückt ist, setzte ich eine globale Variable im ISR auf
TRUE (oder so ähnlich) :-). Ist doch viel besser oder ?!
>wenn Taste gedrückt ist, setzte ich eine globale Variable im ISR auf>TRUE (oder so ähnlich) :-). Ist doch viel besser oder ?!
Wenn meinen Pseudocode gelesen (und verstanden) hättest, hättest du
erkannt, dass genau das dort gemacht wird!
du hast ja ganz recht, meine Gedanken waren wo anders. Erst druch
>Im ISR wird auch nur der Tastendruck ausgewertet und gemerkt
wurde mir alles klar :-)
Dankeschön
ja natürlich weiß ich das.
was Cimbom vorgeschlagen hat, ist auch gar nicht möglich.
BREAK ist NUR in einer Schleife möglich und darf nicht in einer
if-Anweisung benutzt werden (wenn es sich nicht in einer Schleife
befindet). Daher gehört ein RETURN dort hin, um an das Ende der Funktion
zu springen
@Tasti:
Bevor Du jetzt wieder schreibst: isch weissssss,
erstmal Tutorial lesen !
Da haben sich nämlich Menschen Gedanken gemacht,
damit man sehr schnell ein ordentliches Programm
für Tastenabfrage bekommt.
http://www.mikrocontroller.net/articles/Entprellung
Siehe -> Komfortroutine (C für AVR)
Gruß Sven