Forum: Mikrocontroller und Digitale Elektronik Ausschaltverzögerung in Assembler


von Eugen B. (mukki)


Lesenswert?

moin moin,
ich bin gerade dabei mich in das thema µC einzuarbeiten (habt also 
bishin nachsicht mit mir), als ansporn dafür hab ich mir ein kleines 
project vorgenommen.

nun stecke ich bishin fest, denn unter anderen würde ich gerne eine 
ausschaltverzögerung einbauen in mein assembler programm, nur weiss ich 
nicht genau wie ich das realisieren soll :/

als taktgeber wollte ich den internen benützen (sollte trotz höcheren 
tolleranzen ausreichen), der µC kann auf einen internen einen low takt 
von 128khz eingestellt werden(vielleicht ist das hilfreich).

ausstattung:
programmer: mySmartUSB MKII
board: marke eigen-bau :D
entwicklungsumgebung: AVR Studio 5
µC: attiny13a-20pu (dil8)

Code:
1
.include "tn13Adef.inc"         ; Definitionsdatei für den Prozessortyp einbinden
2
 
3
         ldi r16, 0b11000111    ; Definition der Ein- & Ausgänge
4
         out DDRB, r16
5
 
6
         ldi r16, 0b00111111    ; Interne Pullup-Widerstände für Eingänge Aktivieren
7
         out PORTB, r16
8
9
mainloop:    sbi PORTB, 0    ; Rot AUS
10
             sbi PORTB, 1    ; Grün AUS
11
             cbi PORTB, 2    ; Blau EIN
12
13
             sbis PINB, 3    ; Ziehsignal
14
             rjmp Gruen      ; Sprung zur Grünschleife
15
16
             sbis PINB, 4    ; Behälter
17
             rjmp Rot        ; Sprung zur Rotschleife
18
19
             rjmp mainloop   ; Hauptschleife
20
21
Gruen:  sbi PORTB, 2    ; Blau AUS
22
        cbi PORTB, 1    ; Grün wenn Ziehsignal steht
23
        sbic PINB, 3    ; Sprung zum mainloop überspringen wenn das signal noch ansteht
24
        rjmp mainloop   ; Sprung zur Hauptschleife
25
        rjmp Gruen      ; Schleife Grün
26
27
Rot:    sbi PORTB, 2    ; Blau AUS
28
        cbi PORTB, 0    ; Rot wenn Behälter Leer
29
        sbic PINB, 4    ; Sprung zum mainloop überspringen wenn das signal noch ansteht
30
        rjmp mainloop   ; Sprung zur Hauptschleife
31
        rjmp Rot        ; Schleife Rot

info zum project:
1.
ich habe eine RGB LED und möchte das sie im "standby" blau leuchtet.
wenn das Ziehsignal ansteht soll blau ausgehen und grün angehen.
hier wollte ich die ausschaltverzögerung einbauen(in die grünschleife), 
wenn das signal abfällt soll die led noch ca. 1min lang grün leuchtet 
und dann wieder zum mainloop springen.

2.
ähnlich soll das mit rot funktionieren, also wenn die lichschranke 
meldet das der behälter leer ist soll blau ausgehen und rot angehen.
hier würde ich gerne ein blinken von rot (in der rotschleife) 
realisiehren.
wenn die lichtschranke meldet das der behälter wieder voll ist, springt 
es wieder zum mainloop.

hoffe ihr könnt mir weiterhelfen.
sollten noch weitere informationen benötigt werden sagt einfach bescheid 
;)
von Jörn P. (jonnyp)


Lesenswert?

Wie wär es mit einem Timer setzen?
von Eugen B. (mukki)


Lesenswert?

das hatte ich auch vor, aber wie genau?
hab das zwar hier in tut gelesen aber leider begreife ich das nicht :(
ich weiss nicht ob ich da vielleicht was übersehen habe :/
ab liebsten benütze ich fertige beispiele um das besser nachvollziehen 
zu können, hab gehofft das hier jemand sowas postet ;)
von Vuvuzelatus (Gast)


Lesenswert?

von Eugen B. (mukki)


Lesenswert?

C beispiele hab ich bei meiner suche auch gefunden, nur bräuchte ich 
beispiele die in assembler geschrieben wurden, den ich kann aus C keine 
rückschlüsse daraus ziehen wie man das in assembler hinschreiben könnte 
:(
von Karl H. (kbuchegg)


Lesenswert?

Eugen B. schrieb:
> das hatte ich auch vor, aber wie genau?
> hab das zwar hier in tut gelesen aber leider begreife ich das nicht :(

Was genau begreifst du nicht?

Ein Grundprinzip vieler Timeranwendungen besteht darin, dass eine ISR in 
regelmässigen Zeitabständen aufgerufen wird. So wie das Ticken des 
Sekundenzeigers einer Uhr.

Und über dieses regelmässige Ticken, welches dir eine Basiszeiteinheit 
verschafft, musst du deine Applikation abwickeln.

Wie machst du das denn mit einer Uhr?
Wenn das Ziehsignal weggeht, stellst du eine gedachte Stoppuhr auf 60. 
Und mit jedem Tick deiner Hauptuhr zählst du die Stoppuhr um 1 runter. 
Solange bis du dann endlich irgendwann einmal bei 0 angekommen bist und 
du die LED von grün auf blau zurückschaltest.

Und dasselbe kannst du auch mit deiner Lichtschranke machen.


d.h. die Frage die sich stellt lautet:
Bei jedem Ticken meiner Hauptuhr, was habe ich zu tun?
   * nachprüfen ob die Stoppuhr für das Ziehsignal ungleich 0 ist
     (denn dann läuft diese)
   * ist sie ungleich 0, dann um 1 verringern
     * wenn sie dadurch auf 0 gekommen ist: Led auf blau umschalten

   * nachprüfen ob die Stoppuhr für die Lichtschranke ungleich 0 ist
     (denn dann läuft diese)
   * ist sie ungleich 0, dann um 1 verringern
     * wenn sie dadurch auf 0 gekommen ist: Led auf blau umschalten

und da du alle diese Punkte jede einzelne Sekunde, getrieben von deiner 
Hauptuhr ausführst, spielt es keine Rolle mehr, wann genau das 
Ziehsignal bzw. die Lichschranke von blau auf grün/rot gewechselt wurde. 
Du stellst die LED um und stellst die jeweilige Stoppuhr auf 60. Die 
Vorschrift, die du nebenher bei jedem Sekundentick abarbeitest sorgt für 
das verzögerte ausschalten.

Deine Hauptuhr (der Timer) tickt jetzt nicht jede 1 Sekunde, sondern 
etwas schneller. Das macht aber nichts. Ds sind nur andere Zahlenwerte, 
das Prinzip ist nach wie vor dasselbe.


Register für die Ziehsignal-Stoppuhr sei zb R23
Register für die Lichtschranke-Stoppuhr sei zb R24

Timer-ISR

   R23 gleich 0 ?
    |  nein:   R23 decrementieren
    |          ist es jetzt 0?
    |            ja: LED grün/blau auf blau umschalten
    v
   R24 gleich 0 ?
    |  nein:  R24 decrementieren
    |         ist es jetzt 0?
    |            ja: LED rot/blau auf blau umschalten
    v
  reti

main:
  Eingangpin Ziehsignal abfragen
  Ziehsignal da?
      ja: LED grün/blau auf grün umschalten
          R23 auf 60 Sekunden setzen

  Eingangspin Lichtschranke abfragen
  Behälter leer?
      ja: LED rot/blau auf rot umschalten
          R24 auf 60 Sekunden setzen

  rjmp main


Und das wars schon. Das realisiert deine Ausschaltverzögerung. In der 
Hauptschleife wird das jeweilige Stoppuhr Register ständig erneut auf 60 
Sekunden gesetzt - solange das entsprechende Eingangssignal vorhanden 
ist. Ist es nicht vorhanden, dann unterbleibt das Zurücksetzen auf 60. 
Gleichzeitig wird aber vom Timer regelmässig die ISR aufgerufen und 
zählt die Stoppuhr runter. Wird in der Hauptschleife die Stoppuhr nicht 
wieder auf 60 zurück gesetzt, denn kann die ISR auch ungestört runter 
zählen und wird irgendwann bei 0 sein. Und dann löst sie die 
Ausschaltaktion aus.

Ganz einfach.
In dem Moment, in dem du bei "Zeitsteuerung" an Warteschleifen denkst, 
bist du meistens verraten und verkauft. "Zeitsteuerungen" funktionieren 
fast immer über den Weg, dass man sich mit einem Timer eine "Basisuhr" 
macht die regelmässig in Form eines Aufrufs der ISR tickt. Und in der 
ISR muss man dann einen Weg finden, wie man durch ANalyse des jetzigen 
Zeitpunktes entscheiden kann was zu tun ist.

Also: Ab ins Tutorial und nachlesen wie man
  * einen Timer einschaltet
  * den Timer konfiguriert, dass er eine ISR anspringt
  * man eine ISR schreibt
  * die Berechnungen macht, damit man auch die gewünschten Zeiten
    erhält.

Als Vorübung ist zb das Blinken jede Sekunde einer LED zu sehen 
(natürlich Timer getrieben). Wenn du das hast, hast du schon viel über 
Timer gelernt.
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.