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?
> 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
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