Hallo zusammen ! ich hab ein kleines Problem mit meiner Interrupt Routine. Ich benutze einen HCS12 Mikrocontroller. Habe die Busfrequenz über PLL auf 24 MHz eingestellt. Nun hab ich eine Interrupt Routine programmiert, die mir in bei fallender Flanke eines Eingangssignals ein paar Berechnungen macht und einen Wert in ein Output Compare Timer Register schreibt für eine Impulsausgabe. Habe mit COdewarrior die Buszyklen gemessen, die ich für die ISR benötige, woraus sich ja die minimale Zeit zwischen zwei fallenden Flanken ergibt, in der die ISR noch komplett ausgeführt wird. Bei den Buszyklen komme ich im worst case auf 1054 cycles. Bei einem Bustakt von 24 MHz entsrpicht dies einer Zeit von 43,92µs. Das hieße, dass mein Eingangssignal minimal sagen wir mal alle 44 µs eine fallende Flanke liefern darf, damit die ISR noch korrekt funktioniert. Anhand von Tests mit dem Oszi hab ich aber festgestellt, dass die minimale Zeit, bei der ich noch korrekte Impulsausgabe bekomme, bei etwa 122 µs liegt. Kann mir jemand sagen ob ich in meinen Überlegungen komplett falsch liege oder was da Sache sein könnte ?? Bin relativ neu in Sachen µC. Hab mal die FUnktion Cap1_OnCapture die von der ISR aufgerufen wird angehängt. Grüße Stefan
Um dir mal klar zu werden welchen Takt du hast, aktiviere mal den E-Clock (müsste am PORTE sein) und messe nach. Das ist dann der Busclock und der ist Osc/2. Gleiches gilt bei der Nutzung der PLL. Freescale hat da eine ganz verwirrende Beschreibung von Clock und Takt. Eventuell sind auch einige Register nicht korrekt configuriert (Vorteiler abgeleitet aus dem Busclock). Ansonsten unbedingt den Spurious Interrupt mit einer ISR behandeln. Eventuel ein Portpin toggeln damit du weisst wie oft du da reinkommst. JL
Wie jl schon sagte: BusClock = PLLCLK/2 Wenn also deine PLL mit 24MHz läuft, ist deine BusClock =12MHz. Eventuell musst du auch die Laufzeiten in der Hauptschleife berücksichtigen, in denen z.B. die Interrupts kurz gesperrt sind (falls das bei dir zutrifft). Vielleicht sind bereits andere Ints am Laufen (z.B. Serielle SS), wenn das Signal reinkommt. Dann musst du noch sicherstellen, dass dir der BDM-Debugger nicht reinspuckt, falls der angeschlossen ist.
Erstmal Danke für die Antworten ! Werd mal versuchen die Clock zu messen. Den Einstellungen nach müsste der PLL bei 48 MHz liegen und der Bus damit bei 24 MHz. Insgesamt hab ich 4 Interrupts wobei ich der längsten ( eigentlich das Hauptprogramm) die höchste Prio gegeben hab. Das mit der BDM Schnittstellt hab ich jetzt gar nich beachtet, werd ich auch mal untersuchen. Hab inzwischen auch festgestellt, dass ich bei einer bestimmten Eingangsfrequenz des Capture Signals Aussetzer bei der Impulsausgabe hab. Da scheinen sich die ISR wohl irgendwie in die Quere zu kommen. Bin dann mal wech am Oszi...
Ok erstmal nochmal thx für die Antworten. Habs inzwischen ganz gut hinbekommen. Allerdings habe ich noch eine Frage. Ich kann über das HPRIO Register ja nur einem Interrupt höchste Priorität zuweisen und das wirkt dann auch nur, wenn 2 Interrupts gleichzeitig auftreten. Nun die Frage : Ist es möglich festzulegen, dass 2 Interruptroutinen jede andere Routine unterbrechen können ? Ich würde gerne meine Timer Output COmpare ISRs so konfigurieren, dass sie die Input Capture Routine unterbrechen können. Hoffe ihr könnt mir weiterhelfen ! Gruß Stefan
Ein weiteren Punkt hab ich noch. ab ner bestimmten Eingangsfrequenz des Signals am Input Capture ( ~8,2kHz) fangen meine Output COmpare ISR an sich wild zu verschieben und die capture ISR setzt ab und zu aus ( wird nicht mehr durchlaufen). Rein zeitlich könnten die ISR aber durchaus noch alle abgehandelt werden innerhalb von 2 fallenden Flanken.... Bei 9kHz wird dann gar keine ISR mehr ausgeführt ?!
>Ich kann über das HPRIO Register ja nur einem Interrupt höchste >Priorität zuweisen und das wirkt dann auch nur, wenn 2 Interrupts >gleichzeitig auftreten. Nun die Frage : Ist es möglich festzulegen, >dass 2 Interruptroutinen jede andere Routine unterbrechen können ? Beim HCS12 sind nach Eintritt in eine ISR weitere Ints gesperrt (I-FLAG) (von den nicht maskierbaren und X-maskierten abgesehen) Wenn du in der ISR das I-Flag löscht, können ALLE freigeschalteten Interruptquellen die laufende ISR unterbrechen. Beim Nachfolger S12X wurde der Interrupt-Block umgebaut, kann sein dass es dort nativ so funktioniert, wie du es vorhast. Beim S12 musst du dir irgendwelche SW-Tricks einfallen lassen. Dein externes Triggersignal (so nenne ich es mal), wie fängst du das ein? Über normalen Port_x-Int oder über InputCapture-Int? Warum das ab 8,2kHz nicht mehr funktioniert, kann nur dein Quelltext verraten. PS oben schreibst du: >Insgesamt hab ich 4 Interrupts wobei ich der längsten ( eigentlich das >Hauptprogramm) die höchste Prio gegeben hab. Also ich weis nicht. Ich glaube, du bist ein recht skrupelloser Programmierer. Mach mal ein paar worst-case Überlegungen bez. Laufzeiten und Aufruffrequenzen von ISRs.
Hehe skrupellos kann gut sein :P und danke für die schnelle Antwort. Also ich hab das mit dem I-Bit im CCR Register jetzt eingebaut und scheint zu funktionieren. Die Timing Betrachtungen zu den Interrupt Laufzeiten hab ich inzwischen auch gemacht. Dabei hab ich eben festgestellt, dass die Interrupts ab ner bestimmten Eingangsfrequenz des Eingangssignals ( welches übrigens über Input Capture Timer eingefangen wird) erst beginnen ab und zu auszusetzen oder sich zeitlich zu verschieben, um dann bei ner höheren Frequenz gar nicht mehr ausgelöst zu werden ( getestet mit Oszi und Ausgang am Anfang der ISR setzen und am Ende rücksetzen). Dabei hab ich auch gesehen, dass die ISR sich rein zeitlich gesehen nicht in die Quere kommen, heisst also keine Überlagerung von ISR oder so. Und irgendwie erscheint mir das komisch, wenn die auf einmal aufhören zu funktionieren :) zumindest die Input capture ISR sollte doch eignetlich immer ausgelöst werden, aber auch die setzt irgendwann aus und wird dann gar nicht mehr aktiviert. Mysteriöse Geschichte das :P
Vielleicht noch eine kleine Zusatzfrage, die mich interessieren würde. WIe genau ist das Input Capture ? weil ich hab bei meinem Ausgangsimpuls der ja auf dem erfassten Zeitwert basiert irgendwie 15µs Schwankungen. Habe bereits versucht, einfach nur einen konkreten Wert auf den erfassten Zeitwert zu addieren und da dann nen Impuls per output compare interrupt auszugeben, aber auch da schankt der Impulszeitpunkt um 15µs.
Timer ist derzeit mit 8MHz Bustakt und nem 64er Prescaler betrieben. Heisst also 8µs Timertics.
hab grad mal nen neues Projekt erstellt in Codewarrior nur mit ner Input Capture Routine. 8 Mhz Bustakt und 64 Prescaler. In der Routine wird nurn Port an und wieder aus geschaltet. Und sogar ohne sonstigen Code funktioniert der Inupt Capture nur bis zu einer bestimmen Frequenz ~8,5 kHz.
Vielleicht kannst du den Minimalcode mal posten. Alles Andere wäre nur rätselraten. Bis jetzt weiß ich nichtmal, welchen Prozessor du verwendest.
Prozessor ist : MC9S12C64 Den Code kann ich erst Montag wieder posten, da ich über WE weg bin. Im Prinzip isses aber nur mit codewarrior input capture bean erstellt und in der ISR nen port an und aus schalten. Input capture channel is TC0. CPU is eingestellt auf externe 8 MHz Oszillator Clock und über PLL highspeed mode auf 8 MHz Bustakt gebracht. Naja wie gesagt, kann Montag dann den Code mal posten. Bis dahin schönes WE !
Hi also hab den Fehler gefunden :P Schuld scheint die Hardware zu sein. Irgendwie wird der eingangsimpuls nicht rechtzeitig auf Vcc gezogen um dann eine fallende Flanke zu detektieren. Bin mir noch nicht ganz sicher woran es genau liegt, da der 4N25 Opto eigentlich schnell genug sein müsste aber ok, wenigstens bin ich jetzt weiter. Danke für die Unterstützung ! Gruß
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.