Forum: Mikrocontroller und Digitale Elektronik Grundstruktur zum Taster einlesen und auswerten


von Peter Novell (Gast)


Lesenswert?

Hallo,

ich bin noch ein ziemlicher Anfänger in Assembler. Ich hab bis jetzt 
einwenig mit dem STK rumgespielt, um die Hard- und Software zu 
verstehen. Ich bin nun soweit, dass ich ohne Probleme mit meinen Tastern 
und LED's und einem mega8515 rumspielen kann.

Nun möchte ich mich weiter hinein wagen und dafür brauche ich erstmal 
Grund-Codevorlagen.
Momentan bin ich auf der Suche nach simplen Taster einlese und auswert 
Möglichkeiten sowie Entprellungen.

Also als Entprellung hab ich die Idee, einfach die Taster einzulesen, 
mit einem 10ms Delay entprellen und dann nochmal einlesen und wenn die 
selbe Taste immer noch gedrückt ist, den Tasterdruck akzeptieren.
Ist das so ok? Wie wandle ich das am Besten in Code um?

Wichtig für mich wäre auch noch folgendes. Das Programm soll 
beispielsweise nicht ausgeführt werden, solange eine Taste nicht 
gedrückt wird. Also ich warte also am Anfang des Programms, bis eine 
Taste gedrückt wird, dann lasse ich eine LED leuchten, was signalisiert, 
dass das Programm läuft. Nun komm ich am Ende des Programms wieder in 
die Abfrage ob die Taste gedrückt wurde, da ich mit dieser Taste quasi 
das Programm auch wieder ausschalten will. Nun ist es so, wenn das 
Programm ja sehr kurz ist, ist es schon wieder bei dieser Abfrage wenn 
ich die Taste noch zum einschalten gedrückt halte und das Programm wird 
quasi wieder ausgeschaltet. Wie kann ich das realisieren, dass das 
Programm erst bei einem zweiten Tastendruck ausgeschaltet wird?

Zusätzlich sollen zwischen diesem einschalt und ausschalt Punkt mehrere 
Taster ausgewertet werden.
Jeder Taster führt quasi eine spezielle Funktion aus. Ich hab mir 
gedacht, ich kann die Taster wieder einlesen, entprellen und dann in ein 
Register zwischenspeichern, das erste Register mit irgend einer 
Logischen Verknüpfung verbinden und abfragen ob dieser Taster gedrückt 
wurde. Und dies würde ich dann für jeden meiner Taster machen und bei 
zutreffen die nötige funktion ausführen.

Ihr merkt, eigentlich hätte ich schon einige Ideen, aber wenn ich dies 
in Code umsetzen soll, wird es für mich schwierig.

Aber ich denke ihr Assembler-Cracks könnt mir da weiterhelfen und habt 
sehr warscheinlich auch Code für oben genannte Probleme im Einsatz.
Wäre also über Hilfe und wenn möglich Codebeispiele extrem dankbar.

Grüsse Peter Novell

von df311 (Gast)


Angehängte Dateien:

Lesenswert?

code gibts von mir keinen, dafür ein paar lösungshinweise ;-)

als erstes nimmst du dir das avr-tutorial und fängst an, das 
durchzukauen. gleich am anfang werden taster eingelesn und leds 
geschaltet (das entprellen solltest du vllt. für ein bisschen später 
aufheben, im laufe des tutorials kommen ein paar ideen ;-) ). ob im 
tutorial kontrollstrukturen wie schleifen behandelt werden weiß ich 
nicht auswendig, aber diese sind dann der nächste schritt.

sobald du dann ein bisschen plan von der assembler-programmierung hast 
nimmst du dir ein blatt papier und malst auf, welche "zustände" dein 
programm annehmen soll (z.b. warten auf start, läuft, ende).
dann schreibst du dir mit pfeilen dazu, wo das programm starten soll, in 
welcher reihenfolge die einzelnen zustände ablaufen, bei welchem 
ereignis der zustand gewechselt wird, in welchen zuständen auf ein 
ereignis gewartet wird.

und wenn du diese einzelteile hast, kannst du das programm ganz leicht 
selbst zusammenstöpseln.

viel spaß beim experimentieren...

p.s. ein beispiel für eine skizze befindet sich im anhang; ich weiß, 
meine schrift ist grauenhaft ;-)

von Peter Novell (Gast)


Angehängte Dateien:

Lesenswert?

Vielen dank für dein Antwort.

So ich hab mich heute mal rangesetzt und mich mit dem sauberen Einlesen, 
sprich mit einer vernünftigen Entprellung auseinandergesetzt.

Die AVR-Tutorials kenne ich eigentlich fast alle zum grössten Teil, doch 
das Tutorial zur Flankenerkennung hat mir sehr geholfen;)

Ich hab mir die Aufgabe wie im Anhang gestellt.

Hier ist das Resultat. Ich weiss könnte man bestimmt noch sauberer 
lösen, aber wie findet ihr die Lösung soweit und wie sicher ist meine 
Entprellung?

Starttaste:
1
// Auf Starttaste warten
2
Ein:
3
  rcall  Taster_einlesen        ; Taster einlesen
4
5
  andi  Temp,    $80
6
  cpi    Temp,    $80
7
  brne  Ein              ; Warten bis Taste7 gedrückt wurde
8
9
// Warten bis Starttaste losgelassen wurde
10
Wait_Ein:
11
  rcall  Taster_einlesen        ; Taster einlesen
12
13
  andi  Temp,    $80
14
  cpi    Temp,    $00
15
  brne  Wait_Ein          ; Warten bis Taste 7 losgelassen wurde
16
17
// LED 7 einschalten
18
Starteinstellungen:
19
  ldi    Temp,    $80
20
  com    Temp  out    PORTB,    Temp

Flanke:
1
// Taktflanken einlesen und auswerten
2
Takt_einlesen:
3
    rcall  Taster_einlesen    ; Taster einlesen
4
  
5
    andi  Temp,  $10      ; nur Taste 4 beachten
6
7
  // Nur Flanken annehmen
8
    mov    Key_now, Temp
9
    eor    Key_now, Key_old
10
    mov    Key_old, Temp
11
 
12
    breq   Aus
13
 
14
    and    Temp, Key_now
15
    breq  Aus

Aktion:
1
// Ausgabe
2
  inc    Counter
3
  in    Temp,    PORTB  
4
  com    Temp
5
  cpi    Counter,  $0F
6
  brne  Ausgabe
7
  clr    Counter
8
9
Ausgabe:
10
  andi  Temp,    $F0  
11
  or    Temp,    Counter
12
  com    Temp
13
  out    PORTB,    Temp

Ausschalttaste:
1
// Auf Ausschalttaste überprüfen
2
Aus:
3
  rcall  Taster_einlesen
4
5
  andi  Temp,    $80
6
  cpi    Temp,    $80
7
  brne  Takt_einlesen
8
9
// Auf loslassen der Ausschalttaste warten
10
Wait_Aus:
11
  rcall  Taster_einlesen  
12
  andi  Temp,    $80  
13
  cpi    Temp,    $00
14
  brne  Wait_Aus
15
16
  ser    Temp
17
  out    PORTB,    Temp
18
  rjmp  Ein

Taster_einlesen:
1
// Taster einlesen mit Entprellung //
2
Taster_einlesen:
3
  in    Temp,    PIND  
4
  com    Temp
5
6
  rcall  Delay  
7
  in    Temp2,    PIND
8
  com    Temp2
9
  cp    Temp2,    Temp
10
  brne  Taster_Einlesen  
11
12
  ret

Als Delay hab ich eine 20ms Verzögerung geschreiben.

Würd mich über Kommentare und Verbesserungssvorschläge freuen.

Grüsse Peter

von df311 (Gast)


Lesenswert?

sieht doch schon mal ganz gut aus, wenns dazu noch funktioniert ist ja 
alles bestens.
nur irgendwie stören mich die c/C++-kommentar im asm-code ;-)

von Peter Novell (Gast)


Lesenswert?

Funktionieren tuts ohne Probleme;)

Dies liegt wohl daran, dass ich hauptsächlicht C programmiere;) Wie 
kommentiert man denn ein asm Code am besten?

Grüsse Peter

von df311 (Gast)


Lesenswert?

das "normale" kommentarzeichen im avr-asm ist ";", kommt in deinem code 
auch vor. kommentieren im normalfall wie c-programme - also irgendwas 
zwischen gar nicht und jede zeile ;-)

von Hannes L. (hannes)


Lesenswert?

Also ich kommentiere meist so:
1
tim0_ovf:       ;Interrupt-Handler für Timer0-Überlauf (0,25ms)
2
 in srsk,sreg   ;SREG sichern
3
 inc teiler     ;Zeitscheibe hoch
4
 andi teiler,teilermsk  ;auf 16ms begrenzen
5
 brne tastendauer1  ;jetzt keine Entprellung...
6
7
                ;Entprellroutine (Idee geklaut bei Peter Dannegger...)
8
 in itmp,tapin  ;Tastenport einlesen (gedrückt=L)
9
 com itmp       ;invertieren (gedrückt=H)
10
 andi itmp,inmsk;nur Tasten und Jumper berücksichtigen
11
 eor itmp,tas   ;nur Änderungen werden H
12
 and tz0,itmp   ;Prellzähler unveränderter Tasten löschen (Bit0)
13
 and tz1,itmp   ;Prellzähler unveränderter Tasten löschen (Bit1)
14
 com tz0        ;L-Bit zählen 0,2,->1, 1,3,->0
15
 eor tz1,tz0    ;H-Bit zählen 0,2,->tz1 toggeln
16
 and itmp,tz0   ;Änderungen nur dann erhalten, wenn im Prellzähler
17
 and itmp,tz1   ;beide Bits gesetzt sind (Zählerstand 3)
18
 eor tas,itmp   ;erhaltene Änderungen toggeln alten (gültigen) Tastenstatus
19
 and itmp,tas   ;nur (neu) gedrückte Tastenbits bleiben erhalten
20
 or tfl,itmp    ;und zugehörige Bits setzen (gelöscht wird nach Abarbeitung)
21
 ;in "tas" steht jetzt der gültige Tastenzustand,
22
 ;in "tfl" die Flags der neu gedrückten, noch nicht abgearbeiteten Tasten...
23
Tastendauer:
24
 mov itmp,tas       ;Tastenzustand kopieren
25
 andi itmp,tasten   ;nur Tasten mit Wiederholfunktion stehen lassen
26
 tst itmp           ;ist eine Taste betätigt?
27
 breq Tastendauer0  ;nein, Dauer auf Startwert...
28
 dec twz            ;ja, Zähler runter
29
 brne Tastendauer1  ;Dauer abgelaufen? - nein...
30
 or tfl,itmp        ;ja, noch aktive Tasten übernehmen (alternativ)
31
 ldi twz,twz1       ;und Zähler auf Wiederholwert setzen
32
Tastendauer1:
33
 out sreg,srsk      ;SREG wiederherstellen
34
 reti               ;fertig, zurück...
35
36
Tastendauer0:       ;Reset Dauerzähler
37
 ldi twz,twz0       ;Tastendauerzähler auf Startwert
38
 rjmp Tastendauer1  ;fertig...

Und der kommentierte Code passt vermutlich auch noch zur Fragestellung, 
oder?

...

von Peter Novell (Gast)


Lesenswert?

Vielen dank für eure Antworten. Jo der Code passt, jedoch ist mir das 
entprellen über einen Interrupt momentan noch zu übertrieben, da ich wie 
gesagt erst am Anfang stehe.
Momentan tut meine Variante ihren Job gut. Eine Frage hätt ich noch, 
momentan hab ich ein 20ms Entprelldelay eingebaut, da ich einen Taster 
ausgemessen habe welcher maximal 10ms geprellt hat. Denkt ihr die 20ms 
sind ok und die meisten Taster prellen weniger lang oder soll ich das 
Delay sicherheitshalber hochschrauben?

Grüsse

Peter

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.