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???
da keiner sehen kann, was du gemacht oder nicht gemacht oder falsch gemacht oder vergessen hast..
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!
ist es nicht so, das innerhalb einer interrupt routine die anderen interrupts gesperrt sind?
hallo, habs rausgefunden. mit SEI (in der interruptroutine) gehts
Oh, jemand der sich an verschachtelte Interrupts herantraut... Viel Spaß noch!
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?
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.
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.
niemals nicht ohne wirklich zwingenden Grund machen. Ich habs ehrlich noch nie wirklich gebraucht.
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.
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. ...
@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
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....
Lass den timer doch immer laufen, dann sezt du ihn bei Interupt auf 0, und fertig :)
> 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. ...
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)
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.