Forum: Mikrocontroller und Digitale Elektronik Timer Capture Interrupt


von Thomas808 (Gast)


Lesenswert?

Hi,

ich bin noch ziemlicher Mikrocontroller Neuling und versuche mich gerade 
an einem kleinen Programm (nur so zum Spass und zum lernen).

Ein Input Capture Interrupt zieht von dem aktuellen Timerstand den 
vorherigen ab und die Differenz wird dann per 7-Segment Anzeige 
ausgegeben. Soweit funktioniert das auch sehr gut ausser, dass die 
Anzeige in periodischen Abständen immer mal "zuckt". Ich dachte der 
Grund könnte sein, dass der Timer überläuft und deshalb der vorherige 
Timerstand größer als der neue ist und deshalb die berechnete Differenz 
nichtmehr stimmt.

Ich habe probiert mit einem Sprung in so einem Fall das Setzen des Flags 
das in der Hauptschleife die Ausgabe auslöst zu überspringen aber auch 
das funktioniert irgendwie nicht.

Hier noch mein Code:
1
icp:  
2
    lds    outl,  ICR1L      ; Timertwert (16bit) nach outl und outh kopieren
3
    lds    outh,  ICR1H
4
5
    lds    ticp1,  oldl      ; Den alten Timerwert aus dem Ram nach ticp1 und ticp2 kopieren
6
    lds    ticp2,  oldh
7
8
    sts    oldl,  outl      ; Aktuellen Timerwert in den Ram speichern
9
    sts    oldh,  outh
10
11
    sub    outl,  ticp1      ; Aktueller Timerwert - alter Timerwert = Differenz die zur Anzeige gebracht werden soll
12
    sbc    outh,  ticp2      ; (16bit Rechnung)
13
14
    brcs  end
15
    ser    flag
16
17
end:  reti


Kann mir jemand sagen wo mein Fehler liegt?

Gruß,
Thomas


PS: Wenn ich in den Interrupt so "umbaue" dass der Timerstand einfach 
jedes mal wieder auf 0 zurückgesetzt wird funktioniert es wunderbar ohne 
"zucken". Ich gehe also davon aus, dass der Rest meines Programms 
funktioniert.

von Karl H. (kbuchegg)


Lesenswert?

Thomas808 schrieb:

> Anzeige in periodischen Abständen immer mal "zuckt". Ich dachte der
> Grund könnte sein, dass der Timer überläuft und deshalb der vorherige
> Timerstand größer als der neue ist und deshalb die berechnete Differenz
> nichtmehr stimmt.

Das ist es nicht. Auch in diesen Fällen ergibt die Differenz das 
richtige (vorzeichenlose) Ergebnis.


> Hier noch mein Code:

sieht gut aus.
Das einzige was mich stört: Du sicherst das Status Register innerhalb 
der ISR nicht. In dem Fall in dem deine Berechnung aber unterläuft (und 
dann trotzdem das richtige Ergebnis liefert) wird das Carry Flag 
gesetzt. Da du das SREG aber nicht gesichert hast, wirkt sich das dann 
unter Umständen in anderen Programmbereichen (die durch den Interrupt 
unterbrochen werden) aus. Egal was du in einer ISR machst oder welche 
Register du sonst noch benutzt, das SREG musst du bei Eintritt in die 
ISR sichern und vor dem Verlassen wieder restaurieren. Alles andere ist: 
"Ask for trouble"

von Thomas808 (Gast)


Lesenswert?

Hallo Karl Heinz, vielen Dank für deine Antwort. Mein Problem ist damit 
gelöst :)

Es hat tatsächlich daran gelegen, dass ich das Statusregister nicht 
gesichert habe und mir der Interrupt wohl irgendwo beim multiplexen 
reingepfuscht hat. Blutiger Anfänger halt...


Als nächstes werde ich mal probieren den Wert irgendwie in die Frequenz 
umzurechnen. Im Taschenrechner hat man das ja schnell eingetippt, aber 
wie kann ich im Mikrocontroller den Kehrwert nehmen? Oder gibt es da 
andere Wege um auf die Frequenz zu kommen?


Gruß,
Thomas

von ulrich (Gast)


Lesenswert?

Man muss schon den Kehrwert berechnen, was im Gegensatz zur Differenz 
nicht so einfach ist.  Atmel hat in Appl. Note 200 schon einige 
arithmetik Routinen veröffentlicht. Die nächste Aufgabe ist dann die 
Ausgabe, insbesondere die Wandlung von Binär nach Dezimal.

von Thomas808 (Gast)


Lesenswert?

Danke, das hilft mir schon mal weiter. Jetzt ist also erst mal grübeln 
angesagt :) Ich melde mich wieder.

von H.Joachim S. (crazyhorse)


Lesenswert?

Bin ja eigentlich auch ein Fan davon, wenn man mit Assembler einsteigt.
Aber wenn es an Rechnen geht, ist man mit einer "Hochsprache" besser 
bedient.

Und der Fehler mit dem SREG wäre damit auch nicht passiert. Schau dir 
mal das C-Tutorial an.

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.