Forum: Mikrocontroller und Digitale Elektronik AVR: Timer in interruptroutine nutzen?


von Sebastian Heyn (Gast)


Lesenswert?

Hallo,

ich habe ein Problem: ich konfigurier nen interrupt (int1=falling) in
der interruptroutine benutze ich nen timer, der scheint aber nicht zu
laufen... starte ich den timer ausserhalb der int1-routine funktioniert
er wunderbar. habe ich was übersehen???

von crazy horse (Gast)


Lesenswert?

da keiner sehen kann, was du gemacht oder nicht gemacht oder falsch
gemacht oder vergessen hast..

von Sebastian Heyn (Gast)


Lesenswert?

also:

Config Int1 = Falling
On Int1 int_sub

Config Timer2 = Timer , Prescale = 8
Const Timervorgabe = 6
On Timer2 Timer_irq

Enable Interrupts
enable int1

do
nop
loop
end

int_sub:
do something (wait for some pin)
enable timer2
do something (wait for some pin)
disable timer2
print count_rem
return

Timer_irq:
Timer2 = Timervorgabe
Incr Count_rem
Return

da wird immer 0 als wert ausgegeben. wenn ich aber

Config Timer2 = Timer , Prescale = 8
Const Timervorgabe = 6
On Timer2 Timer_irq

Enable Interrupts

do
do something (wait for some pin)
enable timer2
do something (wait for some pin)
disable timer2
print count_rem
loop
end

Timer_irq:
Timer2 = Timervorgabe
Incr Count_rem
Return


ausführe zählt count_rem ganz normal wie es soll hoch!

von Werner A. (Gast)


Lesenswert?

ist es nicht so, das innerhalb einer interrupt routine die anderen
interrupts gesperrt sind?

von Sebastian Heyn (Gast)


Lesenswert?

hallo, habs rausgefunden. mit SEI (in der interruptroutine) gehts

von TravelRec. (Gast)


Lesenswert?

Oh, jemand der sich an verschachtelte Interrupts herantraut... Viel Spaß
noch!

von Sebastian Heyn (Gast)


Lesenswert?

weshalb?

was sollte ich dabeigroß falsch machen können?

in der timer routine ist lediglich n incr x drin. danach springt er
zurück. können da unvorhergesehene patzer passieren? sollte ich diese
aufgabe lieber auf nen anderen controller auslagern? ich möchte das
remote signal nicht verpassen, deshalb muss diese routine von nem
interrupt ausgelöst werden... oder gibts bessere vorschläge?

von Uwe (Gast)


Lesenswert?

verschachtelte Interrupts

Deine Interrupt-Routine muß reentrant geschrieben sein, d.h. sie muß in
der Lage sein, während der Bearbeitung des ersten Interrupts (und
vielleicht auch noch während der Abarbeitung der ersten
timer-Interrupts) einen weiteren Interrupt derselben Art abzuarbeiten,
da ja die Interrupts (alle) freigegeben sind. Das ist schwieriger, als
es klingt.

von Die Waldfee (Gast)


Lesenswert?

Bei verschachtelten Interrupts kann es zu unvorhersehbaren Fehlern
kommen. Dann funzt das Ding nicht und man sucht sich einen Wolf.
Wenn Du meinst, mit diesem Risiko leben zu können - Deine Entscheidung.
Zeitkritische Interrupts sind mit Bascom (der Code sieht für mich nach
Bascom aus) ziemlich Peng, weil Bascom innerhalb der Interrupts alle
32 Register auf dem Stack sichert und am Ende auch wieder
zurücksichert. Das war damals für mich ein Grund, es nicht zu
verwenden.

von crazy horse (Gast)


Lesenswert?

niemals nicht ohne wirklich zwingenden Grund machen. Ich habs ehrlich
noch nie wirklich gebraucht.

von Sebastian Heyn (Gast)


Lesenswert?

mmhh... habe nur diese zwei interrupts: fernbedienungssignal kommt ->
int ausgelöst, auswerteroutine gestartet

auswerteroutine benötigt timer

mehr nicht.

werde dann wohl nen extra controller für die fernbedienung nehmen
müssen.

von Hannes L. (hannes)


Lesenswert?

Scanne doch einfach mit der Input-Capture-Funktion des Timer1 den
ICP-Pin (und damit dein Signal). Die ermittelten Zeiten der
Flankenwechsel legst du in einem Buffer ab. Nun kann das Hauptprogramm
nach jedem Interrupt den Buffer auf eine gültige Sequenz testen und
ggf. darauf reagieren.

...

von Hubert.G (Gast)


Lesenswert?

@Sebastian
Ich glaube du siehst das ganze zeitilich etwas zu eng. Du brauchst
sicher keinen zweiten Kontroller. Das mit den verschachtelten
Interrupts ist aber sicher sehr kritisch.
Aber es kommt darauf an welchen Kontroller du hast, wieviel RAM und was
läuft noch alles darauf.
Dann ist es überhaupt notwendig den Interrupt zu unterbrechen? Wenn im
Timerinterrupt nur ein incr x drinnen ist, sicher nicht. Wenn du im
anderen Interrupt bist wie kritisch ist es wenn der Timerinterrupt
etwas verzögert wird, oder kann man die Auswerteroutine nicht
ausserhalb des ISR legen.
Ich kann dir in BASCOM (nehme mal an das es das ist) leider nicht
helfen, aber ich habe bisher auch bei schnellen und zeitkritischen
Routinen noch nie die notwendigkeit gehabt eine ISR zu unterbrechen da
sich Auswertungen immer nach aussen legen lassen.

Hubert

von Sebastian Heyn (Gast)


Lesenswert?

mmhh ich benötige den timer, weil ich damit die flanken-längen messe.
das mit dem input capture des timer1 geht leider nicht, weil der die
pwm für das display erzeugt... ich könnte auch bei fallender flanke
eigentlich per software die anderen routinen unterbrechen, mal schauen
wie das läuft....

von Läubi (Gast)


Lesenswert?

Lass den timer doch immer laufen, dann sezt du ihn bei Interupt auf 0,
und fertig :)

von Hannes L. (hannes)


Lesenswert?

> mmhh ich benötige den timer, weil ich damit die flanken-längen
> messe.

Was ist eine "Flanken-Länge"???
Die "Flanke" ist der Wechsel zwischen zwei Pegeln, deren Länge sollte
möglichst kurz sein.
Oder meinst du die H- oder L-Impulsdauer (den Abstand zwischen zwei
unterschiedlichen Flanken) oder gar die Periodendauer (der Abstand
zwischen zwei gleichen Flanken)? Dies kann der ICP-Interrupt sehr gut.


Wer Timer auf 0 setzt, verbaut sich die restlichen Hardware-Features
des Timers. Es ist ohne Weiteres möglich, Timer1 frei durchlaufen zu
lassen und quasi gleichzeitig den ICP-Interrupt, beide OCR-Interrupts
und bedingt den OVF-Interrupt zu nutzen. Zusätzlich kann mit jedem
Externen Pin-Interrupt ein Software-ICP programmiert werden. Und das
alles mit nur einem Timer1. Bedingung: Niemand darf den Timerstand
manipulieren! Alle gereifen nur lesend auf den Timerstand zu!

Lösung:

ICP:
In der ICP-ISR wird vom aktuell eingelesenen Inhalt des ICP-Registers
der (gemerkte) Wert des letzten mal subtrahiert und der aktuelle Wert
für das nächste mal gesichert (gemerkt). Die ermittelte Differenz ist
der gewünschte Wert (Anzahl der Timer-Ticks) seit dem letzten Int.

OCR:
In der OCR-ISR wird das OCR-Register (nicht der Timerstand!)
eingelesen. Dann wird das gewünschte Intervall (Anzahl der Timer-Ticks
bis zum nächsten gewünschten Interrupt) dazuaddiert und der Wert wieder
in das OCR-Register geschrieben. Danach kann man die Arbeit machen,
weshalb man den Interrupt überhaupt nutzen will.

OVF:
Es gibt zyklische Dinge, die zwar eine konstante Frequenz erfordern,
deren absoluter Wert der Frequenz aber relativ unwichtig ist. Nutzt man
den OVF-Interrupt des freilaufenden Timer1 (also ohne Reoad!), so
bekommt man eine stabile Frequenz, deren Wert vom Vorteiler bestimmt
wird. Zählt man in dieser ISR eine Variable hoch, kann man diese von
allen Programmteilen als Referenz für langsame Softwaretimer nutzen.
Damit lassen sich sehr effizient Verzögerungen realisieren, ohne dass
Warteschleifen Rechenzeit vernichten.

Software-ICP:
In der ISR des externen Int. wird der Timerstand ausgelesen und mit dem
(gemerkten) Wert der letzten Messung verrrechnet
(Zeit=Neuwert-Altwert).

Achja, ich habe erst heute hier irgendwo gelesen, dass BASCOM in jeder
ISR alle Register sichern soll. Wenn das wahr ist, dann ist BASCOM für
interruptgesteuerte Programme unbrauchbar, denn das Sichern und
Wiederherstellen aller Register und des SREG in jedem Interrupt ist
eine nicht hinnehmbare Verschwendung von Rechenzeit, die den Controller
sinnlos belastet. Das Geniale an Interrupts ist nämlich, dass man die
ISR extrem kurz halten kann, damit trotz häufigen INT-Aufrufs das
Hauptprogramm kaum langsamer wird. Anders wären Dinge wie Software-PWM
oder Timer-synchronisierte LCD-Ausgabe garnicht möglich.

...

von Sebastian Heyn (Gast)


Lesenswert?

Habe das kleine problemchen ein bisschen unkonventionell gelöst. Wenn
der eingang auf low geht springt er in eine andere routine - sind ein
paar if's mehr :-)) abers stürtzt ned mehr sporadisch ab... (FREU)

von Philipp (Gast)


Lesenswert?

Was wertest du da denn aus? Klingt wie eine Blaupunkt Fernbedienung :)

Ich habe das auch mit einem Timer gelöst und dem ext. Interrupt. Bei
mir setzt eine fallende Flanke den Timer auf 0 und eine steigende gibt
den Timerwert an eine Variable aus der dieser ausgewertet wird. Man
könnte sogar einfach Timer vorher und nacher merken, dann könnte man
den Timer noch für andere Sachen verwenden. Ich messe amit übrigens
auch die Länge des Signals und es funktioniert sehr gut

Gruß Philipp

von Sebastian Heyn (Gast)


Lesenswert?

nein ne nec fernbedienung mit nec code - die wird eingelesen und
umgerechnet. dann wird das geänderte signal fürn andres gerät wieder
ausgegeben. das läuft auch. nur soll der controller auch n display
steuern (er ließt von ner i2c schnittstelle daten ein und errechnet
dmit modus etc und schiebt sie in ein großes 160bit schieberegister
(lcd)

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.