mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Zahlenschloss


Autor: Lukas88 (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Ahem (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Ahem (Gast)
Datum:

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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:
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
taste1up: 
        in      R16,PIND
        andi    R16,0x1f
        cmpi    R16,0x1f
        brne    taste1up   ; warten, bis Taste wieder losgelassen
  
taste2:
        in      R16,PIND
        andi    R16,0x1f    ; Tasten ausmaskieren
        cmpi    R16,0x1d    ; Taste an PD1 abfragen 0b00011101 = 0x1d
        breq    taste2up    ; Taste an PD1 gedrückt --> weiter
        cmpi    R16,0x1f    ; die anderen Tasten abfragen
        brne    tastefalsch ; irgendeine andere Taste gedrückt --> Fehler
        rjmp    taste2
taste2up: 
        in      R16,PIND
        andi    R16,0x1f
        cmpi    R16,0x1f
        brne    taste2up   ; warten, bis Taste wieder losgelassen
  
taste3:
        in      R16,PIND
        andi    R16,0x1f    ; Tasten ausmaskieren
        cmpi    R16,0x1b    ; Taste an PD2 abfragen 0b00011011 = 0x1b
        breq    taste3up    ; Taste an PD2 gedrückt --> weiter
        cmpi    R16,0x1f    ; die anderen Tasten abfragen
        brne    tastefalsch ; irgendeine andere Taste gedrückt --> Fehler
        rjmp    taste3
taste3up: 
        in      R16,PIND
        andi    R16,0x1f
        cmpi    R16,0x1f
        brne    taste3up   ; warten, bis Taste wieder losgelassen

USW...
  

tastefalsch:

Autor: Lukas88 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!!!

Autor: Hannes Lux (Gast)
Datum:

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

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

...

Autor: Lukas88 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!!!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Wegstaben Verbuchsler (wegstabenverbuchsler)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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  :-/

Autor: Lukas88 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Lukas88 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hoppla

das hier:

Fehler
        rjmp    taste1

...bitte wegdenken.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:
taste1:
        in      R16,PIND    ; den Tastenport einlesen
        cmpi    R16,0x1e    ; Taste an PD0 abfragen 0b00011110 = 0x1e
        breq    taste1up    ; Taste an PD0 gedrückt --> weiter
        cmpi    R16,0xff    ; die anderen Tasten abfragen / PD0 ist aus dem Rennen
        brne    tastefalsch ; irgendeine andere Taste gedrückt --> Fehler
        rjmp    taste1
taste1up: 
        in      R16,PIND
        cmpi    R16,0xff    ; alle Taten wieder auf '1'?
        brne    taste1up    ; warten, bis Taste wieder losgelassen
  
taste2:

:
:

tastefalsch:

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.