Forum: Mikrocontroller und Digitale Elektronik myAVR mk2 mit nur einem Taster bedienen - assembler


von Stephan W. (plutokrat)


Lesenswert?

Hallo,

ich möchte eine kleine Steuerung mit nur einem Taster realisieren.
Am mk2 Board habe ich zusätzlich eine 7-Segmentanzeige, 5 poligen 
Dipschalter und 5 leds.

Ich möchte über den Dipschalter einen Wert eingeben, dies mit einem 
Taster bestätigen, dann einen zweiten Wert über den Dipschalter eingeben 
und diesen dann ebenfalls bestätigen, dann soll er beide Werte addieren 
(zum test soll er erstmal 0 ausgeben).

hier ein kurzer Auszug:

mainloop:
 ldi    r18,0b00000110
 out    PORTB,r18
 in    r19,PINC
 sbrs    r19,5
 rjmp    Taster
 rjmp mainloop

 Taster:
 sbi    PORTC,5

 Taster1:
 ldi    r18,0b01011011
 out    PORTB,r18
 in    r20,PINC
 sbrs    r20,5
 rjmp    Auswahl
 rjmp    Taster1

 Auswahl:
 ldi    r18,0b00111111
...


Das problem ist derzeit, dass er sofort nach "Auswahl" springt, ohne in 
der Schleife "Taster1" hängen zu bleiben. wo ist der Fehler?

von Sascha W. (sascha-w)


Lesenswert?

Hallo,

wie ist dein Taster angeschlossen? Gegen GND? Würde zu deiner Auswertung 
passen - aber Pullup angeschlossen oder den internen eingeschaltet?

Aber unabhängig davon wird dein Programm spätestens bein ersten 
Tastendruck bis zum Ende durchlaufen wenn du nach einem Step nicht 
wenigstens auf das loslassen der Taste wartest oder eine Pause machst, 
aber am besten die Taste ordentlich per Software entprellst.

Sascha

von Stephan W. (plutokrat)


Lesenswert?

also der Taster ist gegen GND angeschlossen
http://www.myavr.info/download/produkte/myavr_board_light/techb_schaltplan-myavr-board-light.png

Pullup-Widerstände habe ich zugeschaltet. Hier nochmal der komplette 
Text:

.include "m8def.inc"
 ;------------------------
 main:

 ldi    r16,0x00
 ldi    r17,0xFF

 out    DDRB,r17
 out    DDRD,r17
 out    DDRC,r16
 out    PORTC,r17

 mainloop:
 ldi    r18,0b00000110
 out    PORTB,r18
 in      r19,PINC
 sbrs    r19,5
 rjmp    Taster
 rjmp mainloop

 Taster:
 cbi    PORTC,5

 Taster1:
 ldi    r18,0b01011011
 out    PORTB,r18
 in      r20,PINC
 sbrc    r20,5
 rjmp    Auswahl
 rjmp    Taster1

 Auswahl:
 adc    r19,r21
 ldi    r18,0b00111111
 out    PORTB,r18
 rjmp    Auswahl

So wie du es beschreibst ist es derzeit auch. drück ich den taster, 
springt er sofort nach "Auswahl". wie kann ich dem programm sagen, dass 
es abwarten soll (also abwarten bis taster losgelassen oder pause 
machen)?

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Stephan Wiegelmann schrieb:
> Das problem ist derzeit, dass er sofort nach "Auswahl" springt, ohne in
> der Schleife "Taster1" hängen zu bleiben.
 Warum sollte er da hängen bleiben ?

 PINC.5 ist durch Taster auf Masse gezogen.

: Bearbeitet durch User
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Stephan Wiegelmann schrieb:
> Pullup-Widerstände habe ich zugeschaltet. Hier nochmal der komplette
> Text:

 Soll heissen:
 Hier nochmal der komplette geänderte Text:

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Stephan Wiegelmann schrieb:
> So wie du es beschreibst ist es derzeit auch. drück ich den taster,
> springt er sofort nach "Auswahl". wie kann ich dem programm sagen, dass

 Nein, jetzt tut er das wahrscheinlich nicht.
 Aber es gibt so etwas wie Tasterprellen, dadurch bleibt er so kurz in
 Taster1, dass du es nicht merkst und aus Auswahl kommt er dann nicht
 mehr raus.

von chris (Gast)


Lesenswert?

du kannst das direkt machen mit

sbis   pinc,5   ;überspring befehl wenn high
rjmp   taster

und das warten entweder mit zeitvertreiben

taster:
rcall warte150ms   ;ACHTUNG diese Zeitschleife musst du selbst schreiben

oder

taster:
sbis   pinc,5   ;überspring befehl wenn high
rjmp   taster   ;wenn low dann sprung

von Stephan W. (plutokrat)


Lesenswert?

@Marc Vesely
ups sry. das war der letzte versuch den ich gestern unternommen hatte. 
damit hatte es aber auch nicht richtig funktioniert.

@chris
danke

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

Hallo,

bin immer gespannt wie es so anderen Assembler-Anfängern ergeht.
Tasterprellen ist wirklich meistens ein Thema, was allerdings mit dieser 
Routine von Peter Dannegger keines mehr sein wird.

Es ist ziemlich schwierig zu verstehen, aber das solltest Du Dir 
reinziehen.

Beitrag "Tasten entprellen - Bulletproof"

Da gibt noch ein paar Tips vom Experten, die Du Dir wirklich angewöhnen 
solltest, auch immer schön fleißig Kommentare verwenden sowie Labels, 
das macht die Programme viel durchschaubarer.

file:///E:/Projekte/AVR-Uhr/INDEXG.HTM

Ich weiß zu Anfang, denkt man das braucht man nicht und möchte unbedingt 
nur seine eigenen Vorstellungen vorrantreiben, aber glaub mir, da 
verstrickst Du Dich ganz schnell, wenn Du nicht die grundlegenden Tipps 
der Experten annimmst.


Bernd_Stein

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

chris schrieb:
> und das warten entweder mit zeitvertreiben
>
> taster:
> rcall warte150ms   ;ACHTUNG diese Zeitschleife musst du selbst schreiben
>
 Normalerweise kommt erst die Action, dann das Warten. Und Taster die
 150ms prellen, schmeisst man gleich weg.

> oder
>
> taster:
> sbis   pinc,5   ;überspring befehl wenn high
> rjmp   taster   ;wenn low dann sprung
 Löst das Problem mit Tasterprellen nicht.


Bernd Stein schrieb:
> Es ist ziemlich schwierig zu verstehen, aber das solltest Du Dir
> reinziehen.
 Nein, sollte er jetzt bestimmt nicht.
 Entweder PeDas Routine verwenden oder versuchen, selbst eine zu
 schreiben. Oder Prellen abwarten.
 Besser schreiben als PeDa kann er die bestimmt nicht, verstehen
 hilft ihm auch nicht weiter, die Routine tut genau das, wofür sie
 auch geschrieben wurde - Tasten entprellen - nicht mehr und nicht
 weniger. Nur eben von jemandem geschrieben, der damit niemandem
 Assemblerprogrammieren beibringen will, sondern eine effiziente
 Routine zur Verfügung stellt.

: Bearbeitet durch User
von Stephan W. (plutokrat)


Lesenswert?

ich seh schon, die einfache variante ist, jede aktion mit einem anderen 
taster durchzuführen.

btw: chris hat das problem doch nicht gelöst ... ich hab mich zu schnell 
bedankt.

: Bearbeitet durch User
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Stephan Wiegelmann schrieb:
> ich seh schon, die einfache variante ist, jede aktion mit einem anderen
> taster durchzuführen.
>
 Nein.

> btw: chris hat das problem doch nicht gelöst ... ich hab mich zu schnell
> bedankt.
 Sagte ich doch.

Probiere mal das:
1
.include "m8def.inc"
2
3
.equ  TastPin = 5
4
5
 ;------------------------
6
 main:
7
        ldi     r16, Low(RAMEND)
8
        out     SPL, r16
9
        ldi     r16, High(RAMEND)
10
        out     SPH, r16
11
        clr     r16
12
        out     DDRC, r16
13
        dec     r16
14
        out     PORTC, r16
15
        out     DDRB, r16
16
        out     DDRD, r16
17
18
 mainloop:
19
        ldi     r16, 0b00000110
20
        out     PORTB, r16
21
22
;***** Warten auf den ersten Tasterdruck
23
Tast1:
24
        sbic    PINC, TastPin
25
        rjmp    Tast1
26
;* Taster zum ersten Mal gedruckt
27
Wert1:
28
        ldi     r16, 0b01011011
29
        out     PORTB, r16
30
        ldi     r16, 50
31
        rcall   Dly                    ;* 50ms warten
32
T1_Wait:
33
        sbis    PINC, TastPin          ;* Warte bis Taster losgelassen wird
34
        rjmp    T1_Wait
35
36
;***** Warten auf den zweiten Tasterdruck
37
Tast2:
38
        sbic    PINC, TastPin
39
        rjmp    Tast2
40
;* Taster zum zweiten Mal gedruckt
41
Wert2:
42
        ldi     r16, 0b00111111
43
        out     PORTB, r16
44
;* Mach deine Addition
45
        rcall   Addieren
46
        ldi     r16, 50
47
        rcall   Dly                    ;* 50ms warten
48
T2_Wait:
49
        sbis    PINC, TastPin          ;* Warte bis Taster losgelassen wird
50
        rjmp    T2_Wait
51
;* Und jetzt wieder von vorne anfangen
52
        rjmp    mainloop
53
54
Dly:
55
        ldi     r17, 20
56
Dly1:   ldi     r18, 133
57
Dly2:   dec     r18
58
        brne    Dly2
59
        dec     r17
60
        brne    Dly1
61
        dec     r16
62
        brne    Dly
63
        ret
64
65
Addieren:
66
        adc  r19, r21
67
        ret

 Dly ist auf 8MHz eingestellt.

: Bearbeitet durch User
von Stephan W. (plutokrat)


Angehängte Dateien:

Lesenswert?

irgendwie muss da noch ein Fehler sein, oder ich hab ein Denkfehler.

jetzt ist es so, dass ich kurz die "2" sehe, das Programm also nur kurz 
in der Taster1-Schleife hängen bleibt und sofort weiter geht - ohne das 
ich was drücke.

Ich seh also die "1" (mainloop-schleife) - drücke den Taster - sehe ganz 
kurz die "2"(Taster1-Schleife) , zeigt dann aber sofort die "0" 
(Auswahl-Schleife).


wenn ich allerdings hinter "Loop:"
5x nop eingebe reagiert der Taster teilweise erst nach beim 5 klicken, 
teilweise schon beim ersten klicken, ab und zu springt er sofort in die 
Auswahl.

von chris (Gast)


Lesenswert?

mal ganz ehrlich willst du das so realisieren???

TIP: mit StackPointer und Unterprogrammen arbeiten

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

Marc Vesely schrieb:
>> Bernd Stein schrieb:
>> Es ist ziemlich schwierig zu verstehen, aber das solltest Du Dir
>> reinziehen.
>  Nein, sollte er jetzt bestimmt nicht.
>  Entweder PeDas Routine verwenden oder versuchen, selbst eine zu
>  schreiben. Oder Prellen abwarten.
>
Wahrscheinlich hast Du recht. Er sollte sie jetzt einfach nur 
verwenden. PeDa schrieb einmal, das er kaum ein Programm kenne, das ohne 
Interrupt arbeitet. Warum sollten wir Anfänger also nicht sofort 
lernen mit Interuppts zu arbeiten und sie als eine sehr nützliche 
Grundlage kennenlernen - nämlich als Zeitbasis die mehrfach genutzt 
werden kann. Hier z.B. einmal für das Entprellen und als 
Programmlaufanzeige evtl. noch für das Multiplexen der LED-Anzeige, 
falls diese mal mehr als ein Digit beihhalten wird.

Um gut das Prellen zu zeigen, wäre ein Programm gut, das erstmal bei 
jedem erneuten Tastendruck eine weitere LED einschaltet ( keine, eine, 
zwei, usw. ) bzw. die Segmente a bis g von der 7-Segmentanzeige.
Dies natürlich nicht mit PeDas Entprellroutine sonst sieht man den 
Effekt ja nicht ;-))
Und als sogenannte Programmlaufanzeige ( PLA ) die die einwandfreie 
Funktion des Interrupts anzeigt, könnte der Punkt der 7-Segmentanzeige 
im Sekundentakt blinken.

Das ist das ZIP-File ( *lcdtrtc.zip* )

file:///E:/Projekte/AVR-Uhr/INDEXG.HTM

das man hier findet :

Beitrag "Zeit + Temperatur auf LCD mit AVR"

Und Du ( Stephan Wiegelmann ) und andere Anfänger unbedingt angucken 
sollten, da hier eine " professionelle " Eintasterentprellung mit bei 
ist und Du sehr nützliche Tipps bekommst.
Dazu die *INDEXG.HTM* zuerst öffnen bzw. doppelklicken.


Bernd_Stein

von Bernd S. (Firma: Anscheinend Corner-Cases ;-)) (bernd_stein)


Lesenswert?

Stephan Wiegelmann schrieb:
> Hallo,
>
> ich möchte eine kleine Steuerung mit nur einem Taster realisieren.
>
Hier findest Du eine sehr gute Entprellroutine, die Du unbedingt 
benötigst :

Beitrag "Einzelnen Taster entprellen ASM"



Bernd_Stein

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.