Forum: Mikrocontroller und Digitale Elektronik Bis drei zählen und dann wieder von vorne


von Karl (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich würde gerne per int0 einen Zähler von 0 bis 3 zählen lassen, beim
vierten in0 soll er wieder von vorne anfangen usw.
Das Hochzählen selbst per in0 klappt schon mal, aber das zurückspringen
auf 0 will nicht.
Wenn ich die beiden auskommentierten Zeilen aktiviere, dann zählt
er überhaupt nicht mehr.
Assembliert wird aber einwandfrei

Hat vielleicht irgendjemand eine Idee, woran das liegen könnte?

Viele Grüsse
Karl

von Jens123 (Gast)


Lesenswert?

inc Lauflichtstatus
         cpi Lauflichtstatus, 3  ; Lauflichtstatus wird mit 3
verglichen
         ;breq  nichtstun      ; Falls das der Fall ist, soll nächste
Zeile
          ; also das zurücksetzen des Lauflichtstatus
          ; übersprungen werden
         ldi Lauflichtstatus, 0x00
nichtstun:
reti

von Karl (Gast)


Lesenswert?

Hallo Jens,

klappt innerhalb der Interrupt-Routine komischerweise nicht.
Im normalen Programm ablauf dagegen schon. Oder darf man vielleicht
innerhalb Interrupt-Routinen keine Labels setzen?

Danke
Karl

von Jens123 (Gast)


Lesenswert?

Hi doch, das kannst du...

ich habs mal bei einer Uhr gemacht...


schnipp
TIM2_OVF:
   inc sekunden    ;Durchlaufzaehler (Grundtakt) 1 hoch
   cpi sekunden, 60   ;Grundtakt -> Teiler auf 60s)
   brne weiter    ;Wenn nicht -> jump zu weiter
   ldi sekunden, 0x00
    inc minuten      ; Sekunden -> Minuten hochzaehlen

   ldi temp, 0b11111101

   sbis PINB, 1
   ldi temp, 0b11111111

   ldi r19, 0b11111110
   and temp, r19

   out PORTB, temp

   ldi hightime, 0

   weiter:


  cpi minuten, 60    ;Max Minuten wenn 60 dann inc stunden
  brne weiter_minuten
  ldi minuten, 0x00
  inc stunden

  weiter_minuten:
  cpi stunden, 24    ;Max Stunden wenn 24 dann inc stunden
  brne weiter1
  ldi stunden, 0x00



  weiter1:
   sbic PINB, 0
   rjmp ende


   inc hightime
   cpi hightime,  0x02  ;Zeit des Highsignals fuer den Takt
   brne ende
schnapp***

von Jens123 (Gast)


Lesenswert?

PS: muss dein Controller irgendwie eien record im potschreiben
brechen??



loop:
        out PORTB, Lauflichtstatus      ;r16 ins IO-Register PORTB
ausgeben
rjmp loop

setz das in deine interupt schleife rein

von Volkmar (Gast)


Lesenswert?

Vielleicht mit brne anstelle von breq?

Besser noch auf größer bzw. kleiner testen und nicht auf gleich.

Volkmar

von Philipp Sªsse (Gast)


Lesenswert?

Ich gehe jetzt einfach mal davon aus, daß es nicht daran liegt, daß
das Zurücksetzen im Code oben auskommentiert ist (obwohl, auch solche
Fehler kann es geben).

Auf jeden Fall zählt das Beispiel nicht von 0-3, sondern von 0-2, denn
bei drei machst Du ja schon wieder eine null draus.

Mit

inc Register
andi Register, 3
reti

wäre die Sache übrigens übersichtlich gelöst.

von Andreas Hesse (Gast)


Lesenswert?

Hallo,

sind Deine Tasten richtig entprellt?

Sonst könnte es sein, das der Interrupt mehrfach ausgelöst wird, obwohl
Du nur einen haben willst.

Gruss
Andreas

von Christof Krüger (Gast)


Lesenswert?

Von 0 bis 3 zählen und dann wieder von vorn kann man ganz leicht ohne
"branch", indem man sich immer die oberen 6 bits herausmaskiert.

also:

inc Lauflichtstatus
andi Lauflichtstatus, 0b00000011

Wenn Lauflichtstatus direkt nach dem Inkrementieren dann nämlich gleich
4 ist (binär 0b00000100), dann werden wie gesagt die oberen 6 bits
"gelöscht" und es bleibt 0b00000000 über.

von Christof Krüger (Gast)


Lesenswert?

oh, war ich wohl zu langsam...

von Karl (Gast)


Lesenswert?

Hallo Jens,

habe das breq noch durch ein brne ersetzt und jetzt klappts.

Danke
Karl

von Thomas (Gast)


Lesenswert?

Im diesem Fall könnte man auch ohne Conditionals auskommen, in dem der
Wert einfach mit 00000011b ver'und'et wird. Das löscht die höheren
Bits und nach der drei kommt wieder die null...

von Karl (Gast)


Lesenswert?

@Jens
<quote>
PS: muss dein Controller irgendwie eien record im potschreiben
brechen??
</quote>

Gute Frage. Aber bei mir muss in der entgültigen Fassung ein Lauflicht
laufen, bei dem auch die ausgeschalteten Lampen noch
leicht glimmen. Das mache ich mit Software-PWM innerhalb einer
Riesen-Lauflichtschleife.

Nun habe ich aber 3 verschiedene Lauflichtarten und zwischen diesen
will ich mit meinem Taster umschalten können.
D.h. wenn ich auf meinen Taster drücke, wird über den Interrupt
mein Lauflichtstatus hochgezählt.
Und nun wird je nach Inhalt des Lauflichtes eine der drei
Lauflichtloops laufen gelassen.

Als nächstes kommt dann noch eine Helligkeitserkennung hinein.
Damit wäre das Ding aber auch schon fertig.

@Christoph

geniale Idee. Darauf würde ich bei meinem momentanen Kenntnisstand
nie kommen. Aber wird genauso eingebaut.

@Andreas,

nein, ich habe die Tasten noch nicht entprellt. Die Taster am STK500
sind aber so gut, dass ich es zu 90% schaffe, mit einem Druck nur einen
Interrupt auszulösen. Wenn ich die verschiedenen Lauflichtarten
durchsteppe (und das sind ja nur 3) und ich dabei versehentlich doppelt
triggere, muss ich halt nochmal durch ;-)
Aber du hast natürlich Recht: Ganz sauber ist mein Progrämmchen so noch
nicht.
Wird wohl der übernächste Schritt.

Danke nochmal an euch Alle
Karl

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.