Forum: Mikrocontroller und Digitale Elektronik [AVR-Asm]Zählvariable setzt sich immer zurück


von Torben Lange (Gast)


Lesenswert?

Guten Abend,

ich habe ein Problem mit einer Zählvariablen, die sich immer wieder auf 
den Anfangswert setzt.

Timer-Interrupt:
1
onTC0:    
2
    cli    
3
    dec r20
4
    cpse r20,r21    
5
    rjmp fiep
6
  
7
tint_ende:
8
      ldi  r16,196
9
      out ioTCNT0,r16
10
      sei
11
      reti
Initialisierung:
1
   ldi r20,0xFF
2
   ldi r21,0x00

Unterroutine "fiep"
1
fiep:   ;---Ton 1kHz--------
2
    sbic   pinb, 3          
3
      cbi    portb, 3      
4
    sbis   pinb, 3          
5
    sbi    portb, 3      
6
    ;------------------
7
    rjmp tint_ende

Ich möchte erreichen, dass das Unterprogramm "fiep" nur bei den ersten 
255 Durchläufen des Timers ausgeführt wird. Doch leider fiept es immer.

Ich sitze seit Stunden an diesem Problem und scheinbar helfen mir meine 
Google-Fähigkeiten nicht mehr weiter. Ein Tipp oder eine Lösung wäre 
sehr willkommen.

mit freundlichen Grüßen,
Torben

von spess53 (Gast)


Lesenswert?

Hi

>Ich möchte erreichen, dass das Unterprogramm "fiep" nur bei den ersten
>255 Durchläufen des Timers ausgeführt wird. Doch leider fiept es immer.

Warum auch nicht? Du hast es doch so programmiert.

Mit

>   cpse r20,r21

wird einmal

>    rjmp fiep

übersprungen. Beim nächsten

>    dec r20

ist r20 = $FF und das Spiel geht weiter.

MfG Spess

von spess53 (Gast)


Lesenswert?

Hi

Ergänzung:

wird einmal -> einmal bei r20=0

MfG Spess

von Amateur (Gast)


Lesenswert?

Ich liebe die Zensur!

Natürlich geht der Code keinen etwas an, deshalb hast Du wohl auch alles 
andere rausgeschmissen.

Ich liebe Unterbrechungen ohne jede Sicherung!
Aber Spess hat wohl irgendwie Recht.

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


Lesenswert?

Amateur schrieb:
> Aber Spess hat wohl irgendwie Recht.
Hat er, aber trotzdem sollte man nachsehen, ob einer der Befehle in der 
ISR z.B. das Statusregister ändern. Falls das der Fall ist, dann sollte 
dieses Register gesichert (push) und wieder hergestellt (pop) werden. 
Sonst gibt es diese "seltsamen" Effekte...

Und wozu man ein cli und ein sei in der ISR braucht, ist mir auch nicht 
ganz klar. Beim AVR kann eine ISR doch sowieso nicht unterbrochen 
werden...

Torben Lange schrieb:
> Ein Tipp oder eine Lösung wäre sehr willkommen.
Starte den Simulator...

von Amateur (Gast)


Lesenswert?

>>Falls das der Fall ist, dann sollte
>>dieses Register gesichert (push) und wieder hergestellt (pop) werden.
>>Sonst gibt es diese "seltsamen" Effekte...

Deshalb:
>Ich liebe Unterbrechungen ohne jede Sicherung!

Die Wahrscheinlichkeit ein "richtiges" Programm zu schreiben in dem kein 
Vergleich vorkommt...

von c-hater (Gast)


Lesenswert?

Amateur schrieb:

> Die Wahrscheinlichkeit ein "richtiges" Programm zu schreiben in dem kein
> Vergleich vorkommt...

Das ist wirklich nur sehr selten möglich. Aber eine ISR zu schreiben, 
die die Flags nicht ändert und sie deshalb auch nicht retten muß, das 
geht schon öfters mal zu realisieren.

Allerdings: sobald irgendwas gezählt werden soll, ist das kaum noch 
sinnvoll möglich.

von Thomas (kosmos)


Lesenswert?

Du nimmst dir ein Bit eines Registers oder ein Bit eines SRAM Bytes und 
setzt es mit erreichen von 255 deines Zählregisters auf 1. Am Anfang der 
Fieproutine musst du dann prüfen ob das Bit 0 oder 1 zeigt und dann das 
fielen überspringen.

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.