www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Output Capture beim HC12 Controller


Autor: Fragensteller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen!

Ich arbeite leider zum ersten mal mit dem HC12 Controller von Freescale 
und habe somit ein paar kleine Probleme mit dem Manual auszukommen. 
Bisher hat eigentlich alles ganz gut geklaptt allerdings komm ich beim 
Capture und Compare überhaupt nicht weiter.

Ich habe eine feste Hardware vorgegeben und kann somit das Layout auch 
nicht ändern. Das Problem ist folgendes:

Am Port T habe ich an PT2,4 und 5 eine Hardwaresitzen deren Signale ich 
überwachen muss. Es ist dringend notwendig das diese Signale Interrupt 
gesteuert sind, da ich hier schnelle Antwortzeiten benötige und normales 
Polling zu langsam wäre.

Meines Wissens kann man doch mit der Captureeinheit externe 
Triggersignale zählen. Wenn z.B 10 Pulse gezählt wurden, dann soll 
Interrupt ausgelöst werden. In meinem Programm sollte nach einem Puls 
Interrupt ausgelöst werden, also sprich die Pins sollen als externe 
Interrupts fungieren.

Ich mache jetzt schon zwei Tage daran rum und komme nicht richtig voran, 
daher frage ich einfach mal in die Runde da es sicherlich schon einige 
Leute hier gibt die Erfahrung mit diesem Controller haben.

Meine Init Funktion ist folgende:

  TIOS = 0b00110100;   // channel acts as an output compare

  TCTL3 = 0b00000101; // IOC4,5 captures on rising edges
  TCTL4 = 0b00010000; // IOC2 captures on rising edges

  TIE = 0b00110100;   // Timer Interrupt Enable Register

  // After the first rising edge interrupt is released
  TC2 = 1;
  TC4 = 1;
  TC5 = 1;

So war das eigentlich gedacht. Leider springt das Programm regelmäßig in 
die Routine vom IOC2 obwohl die Ports derzeit noch in der Luft hängen.

Hoffe jemand nimmt die Mühe auf sich mir zu helfen...

Gruß
T.

Autor: APW (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Welcher Prozessor genau (mit Maskennummer) ?
Lass die Input-Ports nicht offen rumhängen (->Pull Up/Down)
Generell lösche ich Int-Flags bevor ich die Ints enable.

> TIOS = 0b00110100;   // channel acts as an output compare
Ist aber output compare, nicht input capture ?

>  TC2 = 1;
>  TC4 = 1;
>  TC5 = 1;
Was soll das bewirken ?

>...Wenn z.B 10 Pulse gezählt wurden, dann soll
>Interrupt ausgelöst werden.
Wenn erst beim 10. Puls ein Int ausgelöst werden soll, ist das event. 
eher ein Fall für die Pulsakkumulatoren, die allerdings an PT0..3 
hängen.

Input Capture löst bei jedem Ereignis (falling/rising/any edge) einen 
Int aus, die du dann SW-mässig zählen musst.

Wieso nimmst du nicht "normale" Int-fähige Porteingänge ?

Autor: Fragensteller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich verwende den 68HC12 - MC9S12C128.

Ich dachte Output Compare ist eben die Pulse zählen und das beim 
Zählerstand 1 die ISR ausgelöst wird.

Die Pulsakkus kann ich ebenfalls nicht verwenden da das Layout schon 
steht. Die Platine neu zu machen wird zu teuer.

Ich muss also die Eingänge als Input Capture stellen ? Die Timer ISR 
Enablen und dann wird bei der eingestellten Flanke eine ISR ausgelöst ? 
Mehr brauche ich gar nicht. Ich probiere das gleich mal und melde mich 
nochmal falls ich kein Erfolg damit habe.

Mal so ganz nebenbei: Welches sind denn die INTfähigen Port Eingänge. 
Das ist doch auch nur der XIRQ und der IRQ Eingang oder ?

Autor: Fragensteller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Leider löst der Interrupt immer wieder aus obwohl an den PINs keine 
Pegel anliegen. Die INIT Funktion sieht nun so aus,

TIOS = 0b11001011;   // channel acts as an intput capture

  TCTL3 = 0b00000101; // IOC4,5 captures on rising edges
  TCTL4 = 0b00010000; // IOC2 captures on rising edges

  TIE = 0b00110100;   // Timer Interrupt Enable Register


wenn ich in die ISR reinkomme:

void INTERRUPT ISR_CollisionDetect(void)
{
...


  INT_ENABLE();  // enable Interrupt Command again
  TFLG1 |= 4;    // clear interrupt flag



...

Autor: Fragensteller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe gerade noch bemerkt das sich die ISR Flags nicht löschen lassen

Im Register steht 0xDF = 1101 1111, es sind also alle Flags auf high.

Jedoch lassen sie sich mit dem Befehl

TFLG1 = 0xFF; // Clear interrupt flags

nicht zurücksetzen.

Autor: Fragensteller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh man. Auslösen tut er tatsächlich weil die Pins in der Luft hängen. 
Dabei hatte ich das Problem bei nem anderen Controller schon einmal :-( 
Ich lerns nie... Hab zur Zeit ne Probehardware an der die Pins eben frei 
liegen. Muss dann nochmal testen wenn die Hardware fertig ist. Also 
vielen Dank !!!

Autor: APW (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ich verwende den 68HC12 - MC9S12C128.
HCS12 ist die Weiterentwicklung von HC12. Sprich also besser von HCS12.
Ich hoffe du verwendest die richtigen Registeradressen.


>Mal so ganz nebenbei: Welches sind denn die INTfähigen Port Eingänge.
Habe überlesen, dass das Layout schon fix ist.
Mit den Int-fähigen Porteigängen meinte ich die KWU-fähigen (Key Wake 
Up) Ports. Beim 9S12C128 sind das die Ports P und J. Die kannst du so 
konfigurieren, dass dort Signalwechsel einen Int auslöst. Damit kannst 
du auch den uC aus dem StopMode (Sleep) holen, deshalb "Key Wake Up".

Ouput Compare nimmst du, wenn du mit dem uC selbst ein Signal erzeugen 
willst. Der entsprechende Timer-Pin ist dann ein Ausgang !

Input Capture misst ein Signal, das dem uC zugeführt wird, der 
entsprechende Port-Pin ist dann ein Eingang ! Wenn also das 
Eingangssignal wechselt(z.B.), wird der Zählerwert des Timer Counter 
Register (TCNT) in das Timer Input Capture Register des entsprechenden 
Kanals übernommen und ein (freigegebener) Int ausgelöst. Du kannst damit 
feststellen, wann genau das Input-Ereignis stattfand, auch wenn die ISR 
erst verspätet angesprungen wird, z.B. weil gerade eine andere ISR 
abgearbeitet wurde.


>void INTERRUPT ISR_CollisionDetect(void)
>{
>...
>  INT_ENABLE();  // enable Interrupt Command again
>  TFLG1 |= 4;    // clear interrupt flag

Das ist mehrfach falsch. Wenn du das so machst, wird diese ISR noch in 
der INT_ENABLE Funktion neu angesprungen (endloser Ablauf). Da wird 
nichts mehr funktionieren, da als erstes der Stack überläuft.

1)In einer ISR brauchst du kein Int-Enable, da beim Rücksprung aus einer 
ISR das gerettete Status-Register vom Stack geholt wird (RTI), damit 
werden die Ints wieder freigeschaltet. Innerhalb der ISR sind die Ints 
gesperrt.

2)Selbst wenn du das so machst (nur für Fortgeschrittene), musst du das 
aktive Interrupt Flag erst löschen, bevor du die Interrupts manuell 
freigibst, sonst wird eben diese ISR sofort nach der Interruptfreigabe 
neu angesprungen.

Autor: Fragensteller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank für deine ausführliche Antwort. Das hilft mir schon wieder 
weiter. Scheinst wohl öfters mit dem Controller gearbeitet zu haben :-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.