Hallo, über InputCapture Interrupt des Mega8515 (läuft mit 16MHz)will ich Flankenwechsel erkennen. Das Hauptprogramm besteht nur aus einer Endlosschleife, in der auf den Timer1_Capture Interrupt gewartet wird. In der ersten Ausführung des InputCapture Interrupt wechselt der Port der LED den Zustand bei jedem Flankenwechsel, egal ob steigend oder fallend. Das funktioniert auch Timer1_Capt: ;==== verwendete Register sichern push r16 ;==== Zeitwert einlesen in r24, ICR1L in r25, ICR1H ;==== wechseln der Flankenerkennung switchFlanks: in r16, TCCR1B sbrs r16, ICES1 rjmp NextIntIsRisingEdge NextIntIsFallingEdge: cbr r16, (1<<ICES1) out TCCR1B, r16 rjmp switchLED NextIntIsRisingEdge: sbr r16, (1<<ICES1) out TCCR1B, r16 ;==== LED umschalten switchLED: sbic PIN_LED, 0 rjmp LED_out LED_on: sbi PORT_LED, 0 rjmp endTimer1_Capt LED_out: cbi PORT_LED, 0 endTimer1_Capt: ;==== verwendete Register wiederherstellen pop r16 reti In der zweiten Ausführung soll die LED nur umschalten, wenn der Interrupt durch eine fallende Flanke ausgelöst wurde. Dazu ersetze ich "rjmp switch LED" in der ersten Ausführung unter "NextIntIsFallingEdge" durch "rjmp endTimer1_Capt", so daß bei einer aktuell gestiegenen Flanke gleich zum Ende des Interrupt verzweigt wird, ohne die LED umzuschalten. DAS FUNKTIONIERT ABER NICHT: mit dem Oszi stelle ich am LED-Pin fest, das dieser unregelmäßig mal bei steigender, mal bei fallender Flanke wechselt, machmal lässt er Flankenwechsel einfach aus, ohne die LED umzuschalten.... Im Datenblatt des Mega8515 steht auch, daß für DutyCycleMessungen ICF1 nach jedem Flankenwechsel mit einer 1 beschrieben werden muss. Warum das gemacht werden muss, verstehe ich sowiso nicht. Aber auch das hat zu keinem Erfolg geführt. (nach jedem Flankenwechsel ausgeführt) ResetICF: in r16, TIFR sbr r16, (1<<ICF1) out TIFR, r16 In einer dritten Ausführung wollte ich dann zuerst mal prüfen, durch welchen Flankenwechsel der Interrupt ausgelöst wurde und dann, immer wenn es sich um eine fallende Flanke handelte, die LED umschalten. Auch das funktionierte nicht und hatte ein ähnlich unregelmäßiges umschalten der LED zur folge. Timer1_Capt: ;=== verwendete Register sichern push r16 ;=== prüfen ob Int durch steigende oder fallende Flanke ausgelöst wurde in r16, TCCR1B sbrc r16, ICES1 rjmp switchFlanks ;Abbruch bei steigender Flanke da kein einlesen des Zeitwerts und kein Umschalten der LED benötigt ;=== Zeitwert einlesen in r24, ICR1L in r25, ICR1H ;=== LED umschalten switchLED: sbic PIN_LED, 0 rjmp LED_out LED_on: sbi PORT_LED, 0 rjmp switchFlanks LED_out: cbi PORT_LED, 0 ;==== wechseln der Flankenerkennung switchFlanks: in r16, TCCR1B sbrs r16, ICES1 rjmp NextIntIsRisingEdge NextIntIsFallingEdge: cbr r16, (1<<ICES1) out TCCR1B, r16 rjmp endTimer1_Capt NextIntIsRisingEdge: sbr r16, (1<<ICES1) out TCCR1B, r16 endTimer1_Capt: ;==== verwendete Register wiederherstellen pop r16 reti Was mache ich denn falsch, oder verstehe ich da grundsätzlich noch irgendetwas falsch am InputCapture??? Vielen Dank für Eure hilfe und sorry für den langen thread!!!
Puuuhhhhh... Schwer nachvollziehbar (kann aber an meiner Müdigkeit liegen)... Hier mal als Beispiel eine funktionierende ICP-ISR, die ein pulsweitenmoduliertes serielles Datentelegramm am ICP-Pin einliest und auf bestimmte Daten reagiert. Die Routine ist Teil eines Zündgerätes für (Klasse 4-) Feuerwerk. .equ basis1=32 ;Gerät 'B' (erster Schuss von Zünduhr) .equ basis2=224 ;Gerät 'H' (darauf reagieren alle Zündverteiler) .equ schuesse=31 ;Anzahl der Schüsse .equ icps=(1<<icnc1)|(1<<ices1)+3 ;Timer1-ICP steigende Flanke, VT=64 .equ icpf=(1<<icnc1)+3 ;Timer1-ICP fallende Flanke, VT=64 impuls: ;ISR Input-Capture Timer 1 (Datenempfang von Zünduhr) ;Achtung, das Signal ist wegen Optokoppler Low-aktiv! in srsk,sreg ;SREG sichern in xl,tccr1b ;aktuelle Flanke ermitteln cpi xl,icpf ;fallende Flanke? (Impulsbeginn) brne impuls_steigend ;nein, steigende impuls_fallend: ;Impulsbeginn (L-aktiv) ldi xl,icps ;ja, ICP auf steigende out tccr1b,xl ;Flanke umschalten in altzeit,icr1l ;Zeitstempel Impulsbeginn holen rjmp impuls_e ;fertig... impuls_steigend: ;Impulsende (L-aktiv) ldi xl,icpf ;ICP auf fallende Flanke out tccr1b,xl ;umschalten in xl,icr1l ;Zeitstempel holen sub xl,altzeit ;Zeitstempeldifferenz etwa 512 oder 1536 cpi xl,16 ;Takte? (8 oder 24, da VT=64, Ergebnis im Carry) ror sr3 ;Carry von oben ins ror sr2 ;Eingangs- ror sr1 ;Schieberegister ror sr0 ;schieben brne impuls_e ;unteres Byte 0? (Präambel) nein... cpi sr1,128 ;Präambel und Startbit? brne impuls_e ;nein... mov xl,sr3 ;Prüfsumme com xl cp xl,sr2 ;korrekt? brne impuls_e ;nein... cp uschuss,sr2 ;Schussnummer geändert? breq impuls_e ;nein... mov uschuss,sr2 ;ja, Änderung übernehmen mov xl,sr2 ;Kopie Uhrschussnummer subi xl,basis2 ;über oberer Basisnummer? brsh impuls_1 ;ja... mov xl,sr2 ;neue Kopie Uhrschussnummer subi xl,basis1 ;über unterer Basisnummer? brlo impuls_e ;nein... impuls_1: inc xl ;Uhr beginnt mit 0, Verteiler mit 1 cpi xl,(schuesse+1) ;Schussnummer gültig? brsh impuls_e ;nein... mov kuschuss,xl ;ja, übernehmen sbr flags,1<<uhrschuss ;Flag für Hauptschleife setzen impuls_e: clr uhrz ;Uhrsignal-Zähler löschen sbr flags,1<<uhrsig ;Uhrsignal vorhanden out sreg,srsk ;SREG wiederherstellen reti ;fertig Die (für dich) relevanten Stellen befinden sich gleich am Anfang der ISR. Ich hoffe, das Programm ist aufgrund der Kommentierung lesbar genug. Neben dem ICP-Interrupt laufen noch 3 andere Interrupts (Timer0-Überlauf, Timer1-OCR1a und -OCR1b). ...
Danke Hannes, ich übernehme mal die für mich relevanten Teile in mein Programm und schaue ob es dann die Flanke richtig erkennt. ...
Es könnte Missverständnisse geben: Mein Programm läuft auf dem AT90S8515 mit Quarz 3,6864MHz. Beim Mega8515 könnte das etwas anders sein, da der Timer1 bedeutend mehr Features hat und damit andere Bits in den Controlregistern. Du müsstest also auch den betreffenden Abschnitt in den Datenblättern beider Controller vergleichen. - Sorry... ...
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.