Hallo, ich habe noch eine Frage in Anlehnung an Beitrag "erstes Programm, Binärzähler. Frage (Mega8)" Und zwar geht es um das Entprellen. Im Tutorial steht für die Verzögerung und die dann folgende Überprüfung: wait1: ldi temp2, $FF wait2: dec temp2 brne wait2 dec temp1 brne wait1 ; ... und nachsehen, ob die Taste immer noch gedrückt ist in temp1, key_pin and temp1, key_now brne loop Doch ich verstehe den Ablauf nicht. In wait1 kommt man auf jeden Fall. Dann wird temp2 voller einsen geschrieben und man gelangt in wait2. Es wird dann als erstes von temp2 die eins subtrahiert. brne wait 2, was dann folgt, heißt meines Wissens, dass er zur Marke wait2 springt, falls die Subtraktion 0 ist. Das ist sie beim ersten Durchlauf aber nicht und es geht weiter: von temp1 wird 1 abgezogen und es wird direkt, nach bereits einem Durchlauf geprüft ob die Taste noch gedrückt ist. Was stimmt an meiner Überlegung nicht? Ich denke es liegt an meinem falschen Verständnis von brne ?!
Hallo, brne heißt Branch (if) Not Equal. Somit wird dekrementiert, bis temp2 auf 0 ist. Es werden 2 Loops verwendet um diese (wahrscheinlich wegen hoher Taktrate) zu verschachteln und eine größere Wartezeit zu erreichen. Am Anfang steht wohl auch noch ein "ldi temp1, irgendwas", oder? Gruß Christian
Hallo, brne -> Branch If Not Equal -> Springe, wenn das Ergebnis NICHT gleich 0 ist. Gruß aus Berlin Michael
>dass er zur Marke wait2 springt, falls die Subtraktion 0 ist
'brne' => branch not equal, also NICHT gleich. Er springt so lange zu
wait2 (Zero-Flag NICHT gesetzt) bis die Subtraktion 0 ist (Zero-Flag
gesetzt), also die Bedingung 'not equal' nicht mehr erfüllt ist.
Danach wird temp1 um 1 erniedrigt und die gleiche Abfrage erfolgt bei
temp1.
Das sind zwei identische Zählschleifen von 255 bis 0 die ineinander
verschachtelt sind.
Ich danke Euch! Muss ich die Schleifen so verschachteln oder kann ich theoretisch auch seperat zwei unabhängige Schleifen durchlaufen lassen? es geht doch hier nur um eine Zeitverzögerung, oder?
Das ist Murks so. Man sollte einen Timertick nehmen wenn den sowies schon hat. Hat man doch eh schon. Nein ?
In diesem Fall zählst du 255 x 255. Wenn du nacheinander zählst sind es nur 2 x 255. Die Verschachtelung musst du sowieso auf die geforderte Verzögerung anpassen, entweder Taktzyklen berechnen oder per Debugger und Stopwatch empirisch ermitteln.
Null hat schon Recht, der Timer-INT ist vorzuziehen. Ich weiß aber nicht für welchen Zweck das Ganze gedacht ist, vielleicht ist die Anwendung so einfach dass es so genügt?
Ich möchte es lernen, das ist der Zweck ;) Also mein kleiner Binärzähler hat nun mit die Entprellung aus dem Tutorial, direkt die erste Lösung. Jedoch muss ich die Tasten schon sehr kurz drücken, damit es richtig funktioiert. Und gelegentlich zählt er auch durch, ohne dass ich irgendetwas drücke. Was kann das sein?
also es schaltet, wenn ich es z.B. nur bewege oder in der Hand halte. Wie unterdrückt man das?
hier mal der Quelltext. Ich habe vor dem Abziehen und ausgeben noch einen Counter reingebaut, das hilft zwar etwas aber ist auch nicht perfekt sbi DDRB,0 sbi DDRB,1 sbi DDRB,2 cbi DDRD,2 sbi PORTD,2 ;----------------------------------------------------------------------- - mainloop: wdr ldi r20, 0b00000000 loop: in r18, PIND mov r4,r18 eor r18,r22 mov r22,r4 breq loop and r4,r18 brne loop ldi r21, 0b11111111 wait1: ldi r27, 0b11111111 wait2: dec r27 brne wait2 dec r21 brne wait1 in r1, PIND and r21, r18 brne loop ldi r21, 0b11111111 wait3: ldi r27, 0b11111111 wait4: ldi r28, 0b00000111 wait5: dec r28 brne wait5 dec r27 brne wait4 dec r21 brne wait3 inc r20 out PORTB, r20 rjmp loop ;----------------------------------------------------------------------- -
So wird das nix... Probiere mal das Programm im Anhang aus. Dann versuche mal zu analysieren, warum es funktioniert. Ich habe es bewusst sehr einfach gehalten, damit Du es verstehen kannst. Schau es Dir auch im Simulator des AVR-Studios an, setze dazu (mit F9) einen Breakpoint auf den ersten Befehl der Interrupt-Routine des Timers, dann kannst Du mit F5 bis zum Breakpunkt laufen lassen und mit F11 im Einzelschritt weitermachen um zu analysieren, was da passiert. Klappe im Workspace PortB und PortD auf, bediene PIND 0..2 mit der Maus, schau was nach 4 Durchläufen passiert. Versuche zu verstehen. ...
Natürlich hat sich ein Fehler eingeschlichen, in der Reset-Routine fehlt noch der Befehl: clr null ;immer 0, braucht man immer mal ...
Vielen vielen Dank! Ich werde mir das ansehen und versuchen zu verstehen. Woran liegt es denn, dass der Schalter offenbar schaltet, ohne dass ich ihn drücke? z.B . wenn alles ruhig auf dem Tisch liegt, gibt es gelegentlich Veränderungen in der Schaltung, so als würde ein Taster gedrückt. Hat das auch was mit dem "nachprellen" zu tun? Aber der Taster wurde ja garnicht erst gedrückt..
Sorry. Bitte verlange nicht von mir, dass ich versuche, Dein wirres Zeugs zu analysieren. Das tu ich mir nicht an. Das hat absolut nichts mit einem Programm zu tun. Etwas mehr Struktur solltest Du da schon reinbringen. Tip am Rande: Benutze keine Codezeilen, die Du nicht verstehst. Schreib' zu jeder Zeile einen Kommentar, was Du damit bezwecken willst. Ansonsten blickst Du selbst nicht durch. ...
Ok. Kein Problem. Ich wollte nur wissen, wie es in der regel dazu kommt, dass eine Schaltung selber schaltet, ohne den entsprechenden Tastendruck und wie man das verhindern kann.
wie gesagt, je nachdem wie ich dann die Platine halte, schaltet es manchmal selber. Manchmal auch nicht. Wenn ich sie z.B. in die Hand nehme, springen die Leds weiter, die Schaltung zählt. Wenn ich sie so lege, dass sie automatisch nichts macht, dann funktioniert das Schalten über den Taster problemlos.
Ich kann an Deinem Code nicht erkennen, wo Du auf das Bit, an dem der Taster angeschlossen ist (PD2?), reagierst, um fesrzustellen, ob er betätigt wurde. Du hast zwar ein 'breq loop' und ein 'brne loop' als bedingte Verzweigung drin, doch die prüfen nicht nur das Bit, an dem der Taster hängt, sondern den gesamten Port-Eingang. Da Du an den unbenutzten Bits keine PullUp-Widerstände aktiviert hast, wirken die (hochohmigen) Eingänge als Antenne und lesen Pegel ein, wie sie gerade Lust haben. Und da Dein Programm nicht nur auf PD2 reagiert, sondern auf den gesamten PIND (in r18 eingelesen) macht es nunmal, was die Antennen so empfangen. Die Dannegger-Routine hat den großen Vorteil, dass sie einen ganzen Port (bis zu 8 Bit breit) logisch mit dem vorherigen Zustand und zwei Prellzähler-Bytes verknüpft (ohne jede bedingte Verzweigung!!) und dabei jedes der 8 Bit des Ports getrennt behandelt. In jedem der beteiligten Bytes liegen parallel die Bits für die 8 Taster. Der Wert eines jeden Bytes ist also nicht als Zahlenwert zu interpretieren, sondern als 8 unabhängige Boolsche Variablen (Bitwerte, ja/nein-Aussagen). Die beiden Prellzähler-Bytes werden dabei nur lokal (aber statisch) gebraucht, das Register für den Tastenzustand ('key_state' bzw. bei mir 'tas') stellt dem Hauptprogramm eine entprellte Kopie des Tastenzustandes aller 8 Tasten bereit, das Register mit den Tastenflags ('key_press' bzw. 'tfl') stellt dem Hauptprogramm für jede der 8 Tasten ein Flag zur Verfügung, das anzeigt, ob diese Taste seit der letzten Abarbeitung erneut gedrückt wurde. Also komfortabler geht es eigentlich nicht mehr. Durch einen ganz kleinen Zusatz zu dieser Routine lässt sich eine Wiederholfunktion einbauen, die bei Dauerdruck wirksam wird und auf einige der Tasten begrenzt werden kann (ist auch im Tutorial erklärt). Auch die Störsicherheit ist enorm. Eine Pegeländerung wird erst dann akzeptiert und übernommen, wenn der neue Pegel 4 Durchläufe hintereinander stabil angelegen hat. Das überlistet sogar die laberigsten Billigtaster. ...
Vielen, vielen Dank! Ich war gestern am verzweifeln und hatte schon garkeine Lust mehr . Aber wenn ich die pullup Widerstd. aktiviere funktioniert es problemlos, lieben dank!
Jochen wrote: > Vielen, vielen Dank! > Ich war gestern am verzweifeln und hatte schon garkeine Lust mehr . Aber > wenn ich die pullup Widerstd. aktiviere funktioniert es problemlos, > lieben dank! Nein, es funktioniert nicht problemlos, es sieht nur so aus. Sobald Du die unbenutzten Portpins für andere Dinge nutzen willst, geht der Zirkus von vorn los... ...
> Sobald Du die unbenutzten Portpins für andere Dinge nutzen willst, geht > der Zirkus von vorn los... Inwiefern?
Gast wrote: >> Sobald Du die unbenutzten Portpins für andere Dinge nutzen willst, geht >> der Zirkus von vorn los... > Inwiefern? Insofern, dass Jochens Programm nicht nur auf Änderung des Bits reagiert, an dem der Taster angeschlossen ist, sondern auf irgendeine Veränderung am gesamten Port. ...
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.