Forum: Mikrocontroller und Digitale Elektronik Zahlenschloss


von Lukas88 (Gast)


Angehängte Dateien:

Lesenswert?

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

von Ahem (Gast)


Lesenswert?

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?

von Ahem (Gast)


Lesenswert?

Kleiner Tip: Dein bisheriges Konzept erledigt beides in einem: Die 
Reihenfolge und ob eine Taste gedrückt wurde.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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

von Lukas88 (Gast)


Lesenswert?

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

von Hannes Lux (Gast)


Lesenswert?

> was hat der befehl "andi" aufsich? r16 wird mit 0x1f multipliziert

Das recherchiere nochmal, AND und Multiplikation ist Zweierlei.
Stichwort: Bitmaske

...

von Lukas88 (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

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

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> 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  :-/

von Lukas88 (Gast)


Lesenswert?

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!

von Lukas88 (Gast)


Lesenswert?

hoppla

das hier:

Fehler
        rjmp    taste1

...bitte wegdenken.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> 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
Noch kein Account? Hier anmelden.