Hallo, ich habe die aufgabe ein Zahlenschloss zu programieren. Nachdem die Tasten 1 - 2 - 3 - 4 (PORTD) in dieser reihenfolge eingeben wurden, soll für ca. 3sec alle LED´s am PORTB leuchten. Bei einer falschen eingabe eines 4 stelligen codes soll für 10 sec durch blinken des PORTB "alarm" gegeben werden. Die abfrage auf die richtige reihenfolge und das 3sekündige anschalten der LED´s bekomme ich hin. jedoch weis ich nicht wie ich es schaffe die Falscheingabe zu realisieren... ich hoffe ihr könnt mir helfen
Dein Code wartet ja solange bis die richtige Taste gedrückt ist. Genauer, wenn die Taste 1 nicht gedrückt ist, prüfst Du erneut ob die Taste 1 gedrückt wurde. Das selbe dann mit den anderen Tasten. Was an diesem Konzept widerspricht der Forderung zu erkennen, ob eine falsche Taste gedrückt wurde?
Kleiner Tip: Dein bisheriges Konzept erledigt beides in einem: Die Reihenfolge und ob eine Taste gedrückt wurde.
> jedoch weis ich nicht wie ich es schaffe die Falscheingabe zu > realisieren... Das geht bei deinem Code nicht: Drück einfach mal alle Tasten --> Sesam öffne dich, das Tor geht auf. Du mußt in jedem Schritt alle Tasten einlesen und bewerten. > Nachdem die Tasten 1 - 2 - 3 - 4 (PORTD) in dieser reihenfolge eingeben > wurden, soll für ca. 3sec alle LED´s am PORTB leuchten. Hast du nur 4 Tasten, oder hast du noch mehr? Du mußt warten, bis die betätigte Taste wieder losgelassen wurde, denn für die 2. Zahl ist z.B. die erste Taste eine falsche Taste :-o Wenn du z.B. 4 "richtige" Tasten gegen Masse schaltend am PD3..0 hast und alle "falschen" zusammengefasst am PD4, dann könnte das so aussehen:
1 | taste1: |
2 | in R16,PIND |
3 | andi R16,0x1f ; Tasten ausmaskieren |
4 | cmpi R16,0x1e ; Taste an PD0 abfragen 0b00011110 = 0x1e |
5 | breq taste1up ; Taste an PD0 gedrückt --> weiter |
6 | cmpi R16,0x1f ; die anderen Tasten abfragen |
7 | brne tastefalsch ; irgendeine andere Taste gedrückt --> Fehler |
8 | rjmp taste1 |
9 | taste1up: |
10 | in R16,PIND |
11 | andi R16,0x1f |
12 | cmpi R16,0x1f |
13 | brne taste1up ; warten, bis Taste wieder losgelassen |
14 | |
15 | taste2: |
16 | in R16,PIND |
17 | andi R16,0x1f ; Tasten ausmaskieren |
18 | cmpi R16,0x1d ; Taste an PD1 abfragen 0b00011101 = 0x1d |
19 | breq taste2up ; Taste an PD1 gedrückt --> weiter |
20 | cmpi R16,0x1f ; die anderen Tasten abfragen |
21 | brne tastefalsch ; irgendeine andere Taste gedrückt --> Fehler |
22 | rjmp taste2 |
23 | taste2up: |
24 | in R16,PIND |
25 | andi R16,0x1f |
26 | cmpi R16,0x1f |
27 | brne taste2up ; warten, bis Taste wieder losgelassen |
28 | |
29 | taste3: |
30 | in R16,PIND |
31 | andi R16,0x1f ; Tasten ausmaskieren |
32 | cmpi R16,0x1b ; Taste an PD2 abfragen 0b00011011 = 0x1b |
33 | breq taste3up ; Taste an PD2 gedrückt --> weiter |
34 | cmpi R16,0x1f ; die anderen Tasten abfragen |
35 | brne tastefalsch ; irgendeine andere Taste gedrückt --> Fehler |
36 | rjmp taste3 |
37 | taste3up: |
38 | in R16,PIND |
39 | andi R16,0x1f |
40 | cmpi R16,0x1f |
41 | brne taste3up ; warten, bis Taste wieder losgelassen |
42 | |
43 | USW... |
44 | |
45 | |
46 | tastefalsch: |
danke für die schnellen antworten. @lothar, erst mal danke für die ausfühliche lösung!! muss mich jetzt da mal dahinterklemmen! was hat der befehl "andi" aufsich? r16 wird mit 0x1f multipliziert, wo und wie wird dann das ergebnis weiter verwendet? eines ist mir aufgefallen: angenommen keine taste wird betätigt taste1: in R16,PIND andi R16,0x1f ; Tasten ausmaskieren cmpi R16,0x1e ; Taste an PD0 abfragen 0b00011110 = 0x1e breq taste1up ; Taste an PD0 gedrückt --> weiter cmpi R16,0x1f ; die anderen Tasten abfragen brne tastefalsch ; irgendeine andere Taste gedrückt --> Fehler rjmp taste1 in r16 steht ja dann 0x00, wird dann nicht sofort in tastefalsch "gesprungen"? muss dann nicht nach cmpi r16,0x1e ein brne nach taste 1 kommen? danke!!!
> was hat der befehl "andi" aufsich? r16 wird mit 0x1f multipliziert
Das recherchiere nochmal, AND und Multiplikation ist Zweierlei.
Stichwort: Bitmaske
...
Ok, das "andi" bedeutet ja dass r16 mit dem bitmuster verundet wird. Ich kann jetzt aber trotzdem nichts damit anfange... Kann ich den befehl nicht einfach weglassen?? helft mir bitte, für was brauche ich diesen befehl und wo wird dass ergebnis daraus weiterverarbeitet Danke!!!
Lukas88 schrieb: > Ok, das "andi" bedeutet ja dass r16 mit dem bitmuster verundet wird. Ich > kann jetzt aber trotzdem nichts damit anfange... Ja dann machen wir das jetzt mal an einem Beispiel r16 enthalte zb 11111111 und du AND mit 00001100 Jedes Bit der Maske wird mit dem entsprechenden Bit in r16 ver-undet UND: 0 und 0 -> 0 0 und 1 -> 0 1 und 0 -> 0 1 und 1 -> 1 Das Ergebnis 00001100 Hmm. Da sind jetzt alle 1-en in r16 weg, bei denen in der Maske eine 0 war. Nochmal mit anderen Zahlen r16 10101010 andi 00001100 Ergebnis 00001000 Jaaa: Das AND sorgt dafür, dass alle Bits bei denen in der Maske eine 0 war, definitiv zu 0 werden. Bei denen, bei denen in der Maske eine 1 war, hängt es davon ab, was im anderen Partner war. War da 1, dann ist auch im Ergebnis eine 1, war da 0, dann ist auch im Ergebnis eine 0. -> Man kann also mit dem AND definiert in einem Byte nur die Bits übrig lassen, die einen interessieren. Alle anderen werden definitiv zu 0 > Kann ich den befehl nicht einfach weglassen?? Nein. Du sollst verstehen lernen, wofür man Befehle einsetzen kann. Es ist eine Sache zu wissen, dass das ein UND ist. Eine ganz andere Sache ist es aber, zu wissen was man damit so alles treiben kann. Nur so kannst du dann in der Umkehrung die richtige 'Technik' auswählen, wenn du ein bestimmtes Problem hast.
> Kann ich den befehl nicht einfach weglassen??
Seltsame Frag bzw. Annahme. Glaubst du etwa, der steht da weil noch ein
paar Befehle übrig sind, die man noch los werden möchte? Oder könnte so
etwas doch eher einen (für dich momentan noch nicht identifizierten)
"zweckmäßigen" Grund haben?
> Kann ich den befehl nicht einfach weglassen??
Du kannst ihn weglassen, wenn du schaltungsmäßig dafür sorgst, dass
auf den ungenutzen Pins immer '0' hereinkommt. Dazu mußt du sie aber auf
Masse verdrahten. Und wer verschenkt schon gern 3 IO-Pins :-/
Zuerst möchte ich mich bei Verbuchsler für meine leienhafte frage entschuldigen... jedoch lasse ich nicht locker und habe eine weitere frage zum addi befehl: lothar ging in seinem programm von 4 tastern aus, die anderen wurden einfach zusammen auf einen PIN geschalten. Angenommen diese verdrahtung ist nich möglich, d.h. auch die "falschen" taster leigen jeweils separat an einem PIN. müsste dann die abfrag so aussehen? --> PD0 wird abgefragt, ist dieser betätigt soll zu taste1up gesprungen werden. taste1: in R16,PIND andi R16,0xff ; Tasten ausmaskieren cmpi R16,0xfe ; Taste an PD0 abfragen 0b11111110 = 0xfe breq taste1up ; Taste an PD0 gedrückt --> weiter cmpi R16,0xff ; die anderen Tasten abfragen brne tastefalsch ; irgendeine andere Taste gedrückt --> Fehler rjmp taste1 Danke!
Lukas88 schrieb: > Angenommen diese verdrahtung ist nich möglich, d.h. auch die "falschen" > taster leigen jeweils separat an einem PIN. > > müsste dann die abfrag so aussehen? > --> PD0 wird abgefragt, ist dieser betätigt soll zu taste1up gesprungen > werden. > taste1: > in R16,PIND > andi R16,0xff ; Tasten ausmaskieren Nein. Du willst haben, dass nur das Bit 0 vom PIND übrig bleiben soll. Alle anderen Bits sollen 0 werden. Also muss deine Maske 0b00000001 sein. -> Eine 1 an der Stelle, welches Bit übrig bleiben soll. andi R16, 0x01 ; 0b00000001 > cmpi R16,0xfe ; Taste an PD0 abfragen 0b11111110 = 0xfe Das geht jetzt so auch nicht mehr. Da der ANDI nur das Bit 0 übrig gelassen hat, kann das Ergebnis nur noch entweder 0b00000000 oder 0b00000001 sein. Je nachdem ob die Taste gedrückt war oder nicht. Bei einer gedrückten Taste, wenn ich mich recht an den Code weiter oben erinnere, ist das Bit bei dir 0 cmpi R16, 0x00 breq taste1up Du musst die Masken und die Auswertung an deine Tasten anpassen. Mit dem ANDI setzt du gezielt alle Bits, die NICHTS mit der dich interessierenden Taste zu tun haben auf 0. Und mit dem Compare vergleichst du dann ob die übrig gebliebenen Bits auf 0 oder 1 stehen. Das ist doch nicht so schwer. Denk einfach mal an die Schablonen mit denen Lehrer heutzutage diese Multiple Choice Tests auswerten (Stück Plastik mit Löchern an den richtigen Stellen). Das drauflegen dieser Schablone ist dein ANDI. Durch die Löcher siehst du nur noch die Felder, die richtig sind. Und mit dem cmpi vergleichst du jetzt, ob du in den Löchern das siehst, was du sehen willst.
> Also muss deine Maske 0b00000001 sein.
Das wäre richtig, wenn die Taste gegen Vcc schalten würde. Meine Annahme
war, die Taster würden gegen GND schalten, dann stimmt der Code
eigentlich.
Allerdings ist eine Ausmaskierung mit 0xff unnötig.
Wenn an allen 8 Pins von Port D Tasten hängen, und die Tasten von
PD0..PD3 in dieser Reihenfolge betätigt werden müssen, sieht die Abfrage
der Taste 0 so aus:
1 | taste1: |
2 | in R16,PIND ; den Tastenport einlesen |
3 | cmpi R16,0x1e ; Taste an PD0 abfragen 0b00011110 = 0x1e |
4 | breq taste1up ; Taste an PD0 gedrückt --> weiter |
5 | cmpi R16,0xff ; die anderen Tasten abfragen / PD0 ist aus dem Rennen |
6 | brne tastefalsch ; irgendeine andere Taste gedrückt --> Fehler |
7 | rjmp taste1 |
8 | taste1up: |
9 | in R16,PIND |
10 | cmpi R16,0xff ; alle Taten wieder auf '1'? |
11 | brne taste1up ; warten, bis Taste wieder losgelassen |
12 | |
13 | taste2: |
14 | |
15 | : |
16 | : |
17 | |
18 | tastefalsch: |
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.