Forum: Mikrocontroller und Digitale Elektronik HCS12 Interrupt Time


von NixWisser1982 (Gast)


Angehängte Dateien:

Lesenswert?

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

von NixWisser1982 (Gast)


Lesenswert?

korrigiere Buszyklus in CPU cycles.....genau kapier ich das eh ned :)

von NixWisser1982 (Gast)


Lesenswert?

jemand ne Idee ?

von jl (Gast)


Lesenswert?

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

von APW (Gast)


Lesenswert?

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.

von NixWisser1982 (Gast)


Lesenswert?

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...

von NixWisser1982 (Gast)


Lesenswert?

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

von NixWisser1982 (Gast)


Lesenswert?

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 ?!

von APW (Gast)


Lesenswert?

>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.

von NixWisser1982 (Gast)


Lesenswert?

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

von NixWisser1982 (Gast)


Lesenswert?

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.

von APW (Gast)


Lesenswert?

Mit welchem Takt betreibst du denn dein Timer-Modul ?

von NixWisser1982 (Gast)


Lesenswert?

Timer ist derzeit mit 8MHz Bustakt und nem 64er Prescaler betrieben. 
Heisst also 8µs Timertics.

von NixWisser1982 (Gast)


Lesenswert?

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.

von APW (Gast)


Lesenswert?

Vielleicht kannst du den Minimalcode mal posten. Alles Andere wäre nur 
rätselraten. Bis jetzt weiß ich nichtmal, welchen Prozessor du 
verwendest.

von NixWisser1982 (Gast)


Lesenswert?

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 !

von NixWisser1982 (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.