Taster,Atmega 8

Gast #2771532
Lesenswert?

Grüße euch

Ich hab ein kleine Frage zu meinem Programm. Es soll beim betätigen 
eines Tasters eine LED aufleuchten und beim erneuten betätigen des 
gleichen Tasters soll die LED wieder ausgehen. Bei meinem geschrieben 
Programm funktioniert dies aber nicht immer obwohl ich die LED betätige 
geht die LED nicht aus oder an. Kann mir mal einer helfen?

.nolist
.include    "m8def.inc"
.list


ldi    r16, 0x01
out    DDRD,r16

sbi    PORTD, PD7

rjmp  main

main:


sbic  PIND, PD7
rjmp  main


loop2:
sbi    PORTD, PD0

sbic  PIND, PD7
rjmp  loop2

cbi    PORTD, PD0

rjmp  main
#2771547
Lesenswert?

marvin schrieb:
> Grüße euch
>
> Ich hab ein kleine Frage zu meinem Programm. Es soll beim betätigen
> eines Tasters eine LED aufleuchten und beim erneuten betätigen des
> gleichen Tasters soll die LED wieder ausgehen. Bei meinem geschrieben
> Programm funktioniert dies aber nicht immer obwohl ich die LED betätige
> geht die LED nicht aus oder an.

Ich denke nicht, dass du physisch in der Lage bist innerhalb weniger 
Mykro-Sekunden eine Taste zu drücken und wieder loszulassen. Denn genau 
solange braucht dein µC bis er das nächste mal überprüft ob du die Taste 
gedrückt hast.

Einen einzelnen Tastendruck (im Gegensatz zur Frage "Ist die Taste 
gerade niedergedrückt?") einwandfrei und sauber zu erkennen ist 
erstaunlicherweise gar nicht so einfach. Es ist schwierig genug, dass 
diesem Themenkreis im Tutorial ein eigener Artikel gewidmet ist. Und der 
steht nicht am Anfang des Tutorials sondern schon mitten drinn, denn 
dazu müssen schon ein paar andere Techniken bekannt sein, wenn man es 
ordentlich machen will.

AVR-Tutorial
Gast #2771588
Lesenswert?

"Ich denke nicht, dass du physisch in der Lage bist innerhalb weniger
Mykro-Sekunden eine Taste zu drücken und wieder loszulassen. Denn genau
solange braucht dein µC bis er das nächste mal überprüft ob du die Taste
gedrückt hast."


Kannst du es mir vielleicht genau erläutern?
#2771632
Lesenswert?

marvin schrieb:
> "Ich denke nicht, dass du physisch in der Lage bist innerhalb weniger
> Mykro-Sekunden eine Taste zu drücken und wieder loszulassen. Denn genau
> solange braucht dein µC bis er das nächste mal überprüft ob du die Taste
> gedrückt hast."
>
>
> Kannst du es mir vielleicht genau erläutern?

Ganz einfach.
Das hier ist ein Ausschnitt aus deinem Code
1
...
2
main:
3

4

5
sbic  PIND, PD7        ; *******************
6
rjmp  main
7

8

9
loop2:
10
sbi    PORTD, PD0
11

12
sbic  PIND, PD7       ; *******************
13
rjmp  loop2
14
...

mit dem ersten SBIC stellst du fest, dass die Taste gedrückt wurde. Wenn 
das der Fall ist, soll es bei LOOP2 weiter gehen. Du schaltest die LED 
ein und mit dem zweiten SBIC möchtest du gerne feststellen ob die Taste 
nochmal gedrückt wurde.

Deine Annahme lautet hier: Zwischen den ersten SBIC und dem zweiten SBIC 
wurde die Taste wieder losgelassen!

Aber: Über wieviel Zeit reden wir denn, die zwischen den ersten SBIC und 
dem zweiten vergeht? Das sind (je nach Taktfrequenz des µC) ein paar µs! 
Und in der Zeit schafft kein Mensch eine Taste zu drücken und wieder 
loszulassen.

D.h. der zweite SBIC reagiert nicht darauf, dass die Taste erneut 
gedrückt wurde. Der reagiert darauf, dass die Taste immer noch gedrückt 
IST!
Und als Folge davon wird eben nicht bei LOOP2 weiter gemacht, sondern 
der RJMP übersprungen, die LED ausgeschaltet und es geht bei MAIN 
weiter. Wo, nebenbei bemerkt, der dortige SBIC feststellen wird, dass 
die Taste immer noch gedrückt ist und damit sofort wieder zu LOOP2 geht, 
die LED wieder einschaltet, der darauf folgende SBIC feststellt, dass 
die Taste immer noch gedrückt ist, die LED wieder ausschaltet usw. usw.

Aus Sicht deines µC ist alles was du tust wie eine Superzeitlupe. Was 
für dich schnell ist, ein Wimpernschlag, ist für deinen µC eine halbe 
Ewigkeit. Egal wie sehr du dich bemühst eine Taste möglichst kurz zu 
drücken und wieder loszulassen, dein µC arbeitet in dieser Zeit ein paar 
Zehntausend Befehle ab. Die Annahme, dass du es schaffst zwischen dem 
ersten SBIC und dem zweiten die Taste wieder loszulassen, so dass der 
zweite SBIC den nächsten Tastendruck erkennen kann, ist fehlerhaft. Denn 
das schaffst du aus Zeitgründen eben nicht.
#2771661
Lesenswert?

Hmmm

Könnte natürlich auch sein, dass dein Verständnis darüber, was du mit 
dem SBIC eigentlich machst, fehlerhaft ist.

Damit stellst du nur den momentanen Zustand des Eingangspins fest. Da 
ist keine wie auch immer geartete Logik involviert, die den Vorgang des 
Niederdrückens feststellt.

Es ist wie das kurzzeitige Reinschauen ins Badezimmer, ob das Licht 
brennt. 'Jawohl, brennt' oder 'Nein, brennt nicht'. Aber du hast damit 
keine Information, ob zwischen den Besuchen im Badezimmer jemand da war 
und das Licht ein oder ausgeschaltet hat.
Gast #2774055
Lesenswert?

danke für ratschläge

ich hab ein neues programm geschrieben, zwar ist die Funktion des 
Programmes diesmal nicht ganz so schlimm wie beim ersten Programm, aber 
immer noch nicht perfekt:(. Kann man einen Taster überhaupt mit der 
Polling-Methode gescheit toogeln oder ist dies nur mit Interrupts 
perfekt möglich?


.nolist
.include    "m8def.inc"
.list


ldi    r16,0x01
out    DDRD, r16

ldi    r16, 0x00
out    PORTD,  r16

sbi    PORTD,PD7    ; Pull-up Widerstand aktivieren

ldi    r16,  0x01
main:


sbic  PIND, PD7
rjmp  main

in    r17,PORTD

eor    r17,r16

out    PORTD,  r17

rjmp   main
Gast #2774090
Lesenswert?

marvin schrieb:
> sry ich habe natürlich meinen Taster nicht entprellt

Dein Programm würde Funktionieren, wenn du den Taster über Hardware 
entprellen würdest. Das Toggeln machst du richtig.

Jetzt lies dir im Tut doch mal das mit dem entprellen durch, da gibt es 
auch glaub auch was ohne Interrupt.
Gast #2774139
Lesenswert?

Probier mal mein Code für eine Taste aus. Das Beispiel ist für pinc1, 
aber as kannst du ja ändern. Hab das jetzt mal auf die schnelle aus 
einem Programm von mir herauskopiert.

Braucht nur ein niederwertiges Register und ein Bit für die Flanke.
Ausserdem Kannst du in der Main jederzeit mit tst Taste prüfen, ob die 
Taste noch gehalten wird, oder losgelassen wurde.


1
.def    taste   =   r1
2
.def  s    =  r5    ;S-Register
3
.def  temp1  =  r16    ;Trash       
4
.def    flags   =   r24
5

6

7
.equ    key     =   0
8

9
.org 0
10
  rjmp  res
11
;***************************************************************************************************************
12
;ISR, ca. alle 2mS
13
;***************************************************************************************************************
14
.org OVF0addr
15
ISR:in    s,sreg    
16

17
  ;-----------------------------------------------------
18
    ;Taste an Port.C1 entprellen
19
  ;-----------------------------------------------------
20
    lsl     taste          ;Eine 0 in Taste schieben
21
    sbic    pinc,1          ;pinc1 testen
22
    inc     taste          ;Wenn nicht gedrückt war, die 0 in eine 1 wandeln
23
    brne    exit          ;Nur wenn 8 Nullen in Taste sind, wurde der Taster die letzten 8 ISRs gehalten
24
    brcc    exit          ;Wenn vor 9 ISRs noch nicht gedrückt war, Tastenflag (Flanke) setzten
25
    sbr     flags,1<<key  
26
exit:
27
  out    sreg,s          ;Statusbits zurücklesen
28
  reti              ;in der Main weitermachen
29
;***************************************************************************************************************
30
;                  --- ENDE ISR ---
31
;***************************************************************************************************************
32

33
res:
34
  ...                ;Deine Init (stack, Ports)
35

36
  clr    flags
37
  ;-------------------------------------
38
  ;Timerinterrupt init
39
  ;-------------------------------------
40
  ldi    temp1,1<<cs00|1<<cs01  ;TC0/64, ISR ca. alle 2mS (8MHz/256/64)
41
  out    TCCR0,temp1
42
  ldi    temp1,1<<TOIE0      ;Timer0 overflow interrupt
43
  out    TIMSK,temp1
44
  ;-------------------------------------
45
  ;Hauptprogramm
46
  ;-------------------------------------
47
main:
48
  sbrc  flags,key
49
  rjmp  taste_gedr
50

51
  ...                ;Dein Code
52

53
  rjmp  main
54
  ;-------------------------------------
55
  ;Taste wurde gedrückt
56
  ;-------------------------------------
57
taste_gedr:
58

59
  cbr    flags,1<<key
60

61
  ...                ;Dein Code
62

63
  rjmp  main

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren