Grüße euch
Ich hab ein kleine Frage zu meinem Programm. Es soll beim betätigen
eines Tasters eine LED aufleuchten und beim erneuten betätigen des
gleichen Tasters soll die LED wieder ausgehen. Bei meinem geschrieben
Programm funktioniert dies aber nicht immer obwohl ich die LED betätige
geht die LED nicht aus oder an. Kann mir mal einer helfen?
.nolist
.include "m8def.inc"
.list
ldi r16, 0x01
out DDRD,r16
sbi PORTD, PD7
rjmp main
main:
sbic PIND, PD7
rjmp main
loop2:
sbi PORTD, PD0
sbic PIND, PD7
rjmp loop2
cbi PORTD, PD0
rjmp main
marvin schrieb:> Grüße euch>> Ich hab ein kleine Frage zu meinem Programm. Es soll beim betätigen> eines Tasters eine LED aufleuchten und beim erneuten betätigen des> gleichen Tasters soll die LED wieder ausgehen. Bei meinem geschrieben> Programm funktioniert dies aber nicht immer obwohl ich die LED betätige> geht die LED nicht aus oder an.
Ich denke nicht, dass du physisch in der Lage bist innerhalb weniger
Mykro-Sekunden eine Taste zu drücken und wieder loszulassen. Denn genau
solange braucht dein µC bis er das nächste mal überprüft ob du die Taste
gedrückt hast.
Einen einzelnen Tastendruck (im Gegensatz zur Frage "Ist die Taste
gerade niedergedrückt?") einwandfrei und sauber zu erkennen ist
erstaunlicherweise gar nicht so einfach. Es ist schwierig genug, dass
diesem Themenkreis im Tutorial ein eigener Artikel gewidmet ist. Und der
steht nicht am Anfang des Tutorials sondern schon mitten drinn, denn
dazu müssen schon ein paar andere Techniken bekannt sein, wenn man es
ordentlich machen will.
AVR-Tutorial
"Ich denke nicht, dass du physisch in der Lage bist innerhalb weniger
Mykro-Sekunden eine Taste zu drücken und wieder loszulassen. Denn genau
solange braucht dein µC bis er das nächste mal überprüft ob du die Taste
gedrückt hast."
Kannst du es mir vielleicht genau erläutern?
marvin schrieb:> "Ich denke nicht, dass du physisch in der Lage bist innerhalb weniger> Mykro-Sekunden eine Taste zu drücken und wieder loszulassen. Denn genau> solange braucht dein µC bis er das nächste mal überprüft ob du die Taste> gedrückt hast.">>> Kannst du es mir vielleicht genau erläutern?
Ganz einfach.
Das hier ist ein Ausschnitt aus deinem Code
1
...
2
main:
3
4
5
sbic PIND, PD7 ; *******************
6
rjmp main
7
8
9
loop2:
10
sbi PORTD, PD0
11
12
sbic PIND, PD7 ; *******************
13
rjmp loop2
14
...
mit dem ersten SBIC stellst du fest, dass die Taste gedrückt wurde. Wenn
das der Fall ist, soll es bei LOOP2 weiter gehen. Du schaltest die LED
ein und mit dem zweiten SBIC möchtest du gerne feststellen ob die Taste
nochmal gedrückt wurde.
Deine Annahme lautet hier: Zwischen den ersten SBIC und dem zweiten SBIC
wurde die Taste wieder losgelassen!
Aber: Über wieviel Zeit reden wir denn, die zwischen den ersten SBIC und
dem zweiten vergeht? Das sind (je nach Taktfrequenz des µC) ein paar µs!
Und in der Zeit schafft kein Mensch eine Taste zu drücken und wieder
loszulassen.
D.h. der zweite SBIC reagiert nicht darauf, dass die Taste erneut
gedrückt wurde. Der reagiert darauf, dass die Taste immer noch gedrückt
IST!
Und als Folge davon wird eben nicht bei LOOP2 weiter gemacht, sondern
der RJMP übersprungen, die LED ausgeschaltet und es geht bei MAIN
weiter. Wo, nebenbei bemerkt, der dortige SBIC feststellen wird, dass
die Taste immer noch gedrückt ist und damit sofort wieder zu LOOP2 geht,
die LED wieder einschaltet, der darauf folgende SBIC feststellt, dass
die Taste immer noch gedrückt ist, die LED wieder ausschaltet usw. usw.
Aus Sicht deines µC ist alles was du tust wie eine Superzeitlupe. Was
für dich schnell ist, ein Wimpernschlag, ist für deinen µC eine halbe
Ewigkeit. Egal wie sehr du dich bemühst eine Taste möglichst kurz zu
drücken und wieder loszulassen, dein µC arbeitet in dieser Zeit ein paar
Zehntausend Befehle ab. Die Annahme, dass du es schaffst zwischen dem
ersten SBIC und dem zweiten die Taste wieder loszulassen, so dass der
zweite SBIC den nächsten Tastendruck erkennen kann, ist fehlerhaft. Denn
das schaffst du aus Zeitgründen eben nicht.
Hmmm
Könnte natürlich auch sein, dass dein Verständnis darüber, was du mit
dem SBIC eigentlich machst, fehlerhaft ist.
Damit stellst du nur den momentanen Zustand des Eingangspins fest. Da
ist keine wie auch immer geartete Logik involviert, die den Vorgang des
Niederdrückens feststellt.
Es ist wie das kurzzeitige Reinschauen ins Badezimmer, ob das Licht
brennt. 'Jawohl, brennt' oder 'Nein, brennt nicht'. Aber du hast damit
keine Information, ob zwischen den Besuchen im Badezimmer jemand da war
und das Licht ein oder ausgeschaltet hat.
danke für ratschläge
ich hab ein neues programm geschrieben, zwar ist die Funktion des
Programmes diesmal nicht ganz so schlimm wie beim ersten Programm, aber
immer noch nicht perfekt:(. Kann man einen Taster überhaupt mit der
Polling-Methode gescheit toogeln oder ist dies nur mit Interrupts
perfekt möglich?
.nolist
.include "m8def.inc"
.list
ldi r16,0x01
out DDRD, r16
ldi r16, 0x00
out PORTD, r16
sbi PORTD,PD7 ; Pull-up Widerstand aktivieren
ldi r16, 0x01
main:
sbic PIND, PD7
rjmp main
in r17,PORTD
eor r17,r16
out PORTD, r17
rjmp main
marvin schrieb:> sry ich habe natürlich meinen Taster nicht entprellt
Dein Programm würde Funktionieren, wenn du den Taster über Hardware
entprellen würdest. Das Toggeln machst du richtig.
Jetzt lies dir im Tut doch mal das mit dem entprellen durch, da gibt es
auch glaub auch was ohne Interrupt.
Jürgen schrieb:> Dein Programm würde Funktionieren, wenn du den Taster über Hardware> entprellen würdest.
Sorry, auch dann nicht. Du musst die Flanke (von high nach low)
auswerten, ansonsten eort sich dein m8 zu tode solange du den Taster
haltst.
>"Sorry, auch dann nicht. Du musst die Flanke (von high nach low)>auswerten, ansonsten eort sich dein m8 zu tode solange du den Taster>haltst."
Das verstehe ich jetzt nicht
marvin schrieb:> sbic PIND, PD7> rjmp main
Solange du den Taster hältst, wird rjmp main übersprungen.
Das sind in der Sekunde bei 1 MHz einige 10000 mal.
Probier mal mein Code für eine Taste aus. Das Beispiel ist für pinc1,
aber as kannst du ja ändern. Hab das jetzt mal auf die schnelle aus
einem Programm von mir herauskopiert.
Braucht nur ein niederwertiges Register und ein Bit für die Flanke.
Ausserdem Kannst du in der Main jederzeit mit tst Taste prüfen, ob die
Taste noch gehalten wird, oder losgelassen wurde.
Jürgen schrieb:> cbr flags,1<<key
Ach ja, hier wird das Flag (die Flanke) wieder gelöscht, wenn das nicht
passiert, ist es in etwa dasselbe wie ...
Jürgen schrieb:> marvin schrieb:>> sbic PIND, PD7>> rjmp main>> Solange du den Taster hältst, wird rjmp main übersprungen.> Das sind in der Sekunde bei 1 MHz einige 10000 mal.