Forum: Mikrocontroller und Digitale Elektronik Schalten, nach mehrmaligem Tastendruck


von Meth (Gast)


Lesenswert?

Hallo,

Ich möchte mich im vorhinein für meine Anfängerfrage entschuldigen, 
jedoch beschäftige ich mich erst seit kurzem mit der Materie:
Ich habe folgendes Problem. Nachdem ein Taster mehrmals gedrückt wurde 
(die Anzahl sollte zufällig sein). Sollen sich zwei LEDs einschalten.
Ich arbeite hier mit einem ATTiny 2313. Die LEDs ansich anzusteuern 
stellt kein Problem dar, allerdings finde ich keinen passenden Ansatz um 
dies erst nach mehrmaligem "Tastenhämmern" zu ermöglichen.
Nachdem die Anzahl des Tastendrückens zufällig sein sollte, dachte ich 
mir ich kann mir das Entprellen des Tasters ersparen.

Ich habe euch mal den Code - Teil angehängt.

Danke für eure Hilfe

lg

##########################################################
.include "tn2313def.inc"

.def Temp = r16
.def Input = r17
.def Delay = r18

rjmp main

main:
    sbi ddrb,6 ;Datenrichtung LED1
    sbi ddrb,4 ;Datenrichtung LED2
    sbi ddrb,2 ;Datenrichtung Taster
    ldi Temp, 0
    ldi Input, 20

Loop1:
    sbic pinb, 2    ;wenn Taster gedrückt
    inc Input       ;zähle runter
    cp Input, Temp  ;wenn gleich
    breq Start      ;gehe zu Start
    rjmp Loop1

Start:
    sbi portb, 6
    sbi portb, 4
    rcall Wait
    rjmp main

Wait:
    ldi Delay, 250
W1: dec Delay
    brne W1
    ret

von Karl H. (kbuchegg)


Lesenswert?

Meth schrieb:
> Hallo,

> Nachdem die Anzahl des Tastendrückens zufällig sein sollte, dachte ich
> mir ich kann mir das Entprellen des Tasters ersparen.

Ob das so eine gute Idee ist, ist eine andere Frage, aber seis drumm.

Wichtig ist aber nach wie vor, dass du unterscheidest zwischen

* mache etwas, solange eine Taste gedrückt ist
* mache etwas, wenn eine Taste gedrückt wird

du willst letzteres, hast aber ersteres implementiert

http://www.mikrocontroller.net/articles/AVR-Tutorial:_Tasten

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


Lesenswert?

Meth schrieb:
> Nachdem die Anzahl des Tastendrückens zufällig sein sollte, dachte ich
> mir ich kann mir das Entprellen des Tasters ersparen.
Weißt du, wie "Tastenprellen" aussieht? Speziell das deines Tasters?

> Ich habe euch mal den Code - Teil angehängt.
Da ist nichts "Zufälliges" zu sehen...
Du wirst irgendeine Zufallszahl ermitteln müssen. Das könnte z.B. ein 
der Timerwert eines freilaufenden Timers sein, der beim ersten 
Tastendruck ausgelesen wird...

von Peter D. (peda)


Lesenswert?

Meth schrieb:
> Nachdem die Anzahl des Tastendrückens zufällig sein sollte, dachte ich
> mir ich kann mir das Entprellen des Tasters ersparen.

Daß man mit Verzicht auf Entprellen etwas sparen könnte, ist 
kurzsichtig.
Langfristig spart man deutlich mehr Entwicklungszeit, wenn man sich 
einmal damit gründlich beschäftigt und es danach nur noch verwendet.

Und wenn Du wirklich einen guten Zufall haben willst, ist das auch 
nochmal ne recht komplexe Aufgabe.


Peter

von Meth (Gast)


Lesenswert?

Hallo,

Danke vorerst für eure Hilfe. Ich habe mir die Seite angeguckt und habe 
mir den Code "ausgeborgt" ;). Ich habe das ganze jetzt halbwegs nach 
meinen Bedürfnissen umbauen können. Jedoch habe ich jetzt folgendes 
Problem:
Meine Ausgänge verhalten sich invertiert. Leider reicht mein Halbtages - 
Assembler Wissen nicht aus um den Fehler zu finden und um die "Knaben" 
wieder umzupolen. Eventuell könntet ihr mir noch einmal unter die Arme 
greifen.

Liebe Grüße

Meth

.include "2313def.inc"

.def key_old   = r16
.def key_now   = r17

.def temp1     = r18
.def temp2     = r19
.def temp3     = r20
.def temp4     = r21


.equ key_pin   = PIND
.equ key_port  = PORTD
.equ key_ddr   = DDRD

.equ led_port  = PORTB
.equ led_ddr   = DDRB
.equ LED       = 0


      ldi  temp1, 1>>LED
      out  led_ddr, temp1

      ldi  temp1, $00
      out  key_ddr, temp1
      ldi  temp1, $FF
      out  key_port, temp1
      mov  key_old, temp1
main:
  ldi Temp3, 10
  ldi Temp4, 0
  ldi r22, 36
loop:
      in   key_now, key_pin
      mov  temp1, key_now
      eor  key_now, key_old
      mov  key_old, temp1

      breq loop

      and  temp1, key_now

      brne loop

      ldi  temp1, $FF
wait1:
      ldi  temp2, $FF
wait2:
      dec  temp2
      brne wait2
      dec  temp1
      brne wait1

      in   temp1, key_pin
      and  temp1, key_now
      brne loop

      dec Temp3
      cp Temp3, Temp4
      brne loop

Start:
      in   temp1, led_port        ; den Zustand der LED umdrehen
      com  temp1
      out  led_port, temp1
      rcall Wgloop0
      in   temp1, led_port        ; Und aus nach x Sekunden
      com  temp1
      out  led_port, temp1

    rjmp  main

WGLOOP0:  ldi  R23, 140
WGLOOP1:  ldi  R24, 200
WGLOOP2:  dec  R24
          brne WGLOOP2
          dec  R23
          brne WGLOOP1
          dec  R22
          brne WGLOOP0
        ret

von Karl H. (kbuchegg)


Lesenswert?

Meth schrieb:

> Meine Ausgänge verhalten sich invertiert. Leider reicht mein Halbtages -
> Assembler Wissen nicht aus um den Fehler zu finden und um die "Knaben"
> wieder umzupolen. Eventuell könntet ihr mir noch einmal unter die Arme
> greifen.

Eiegntlich sollte man dich schon wieder auf das Tutorial verweisen. 
Diesmal auf das erste Programmierkapitel über Setzen und Löschen von 
Ausgansgport Pins.

Das hier

      in   temp1, led_port        ; den Zustand der LED umdrehen
      com  temp1
      out  led_port, temp1

war ja nur ein Beispiel im Tutorial um irgendwas bei einem Tastendruck 
zu machen, was nicht zu aufwändig ist und trotzdem etwas interessantes 
tut.

Wenn du gezielt einen Portpin auf 0 oder 1 setzen willst, dann benutzt 
du dafür die Befehle

    sbi

und

    cbi

http://www.mikrocontroller.net/articles/AVR-Tutorial:_IO-Grundlagen#Zugriff_auf_einzelne_Bits

also
1
Start:
2
      cbi  led_port, LED
3
      rcall Wgloop0
4
      sbi  led_port, LED
5
6
    rjmp  main

oder eben umgekehrt, je nachdem wie du es benötigst.

von Karl H. (kbuchegg)


Lesenswert?

Hier
1
      ldi  temp1, 1>>LED
2
      out  led_ddr, temp1

noch mal genau nachsehen, wie das heissen muss! Denn ...

> Leider reicht mein Halbtages - Assembler Wissen

... kann ich nicht akzeptieren. Wenn du etwas nicht weißt, dann must du 
das lernen. So funktioniert nun mal Programmierung. Die wichtigsten 
Dingen finden sich alle im Tutorial und es gibt keinen Grund das nicht 
mindestens einmal von Anfang an durchzugehen.

von Meth (Gast)


Lesenswert?

Hi,

Danke für deine Hilfe klappt mittlerweile alles wunderbar.

Ich werde mich jetzt ganz artig hinsetzen und die Tutorials durchackern 
;)

Liebe Grüße

Meth

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.