Ich hätt´ noch einen ganz anderen Ansatz zum Nachdenken anzubieten, der bei mir in einer Modellbau-Anwendung tadellos funktioniert:
Du generiertst mit dem Timer-Interrupt nicht ein Zeit-Raster, in dem der Eingangspin abgefragt wird, sondern Du lässt bei jeder steigenden Flanke auf dem Eingangspin einen Timer starten, und bei der fallenden Flanke wieder stoppen. Nach jedem Stoppen weist Du den gemessenen Timer-Stand einer Variablen zu (Impulslänge), die Du als Array anlegst und durchzählen lässt.
Die Timer-Dimensionierung sollte so ergfolgen, dass der Timer bei Positiv-Impulsdauern über 5ms überläuft. Dadurch kannst Du am Timer-Interrupt den (30ms-) Synchronisationsimpuls erkennen, denn "normale" Steuerimpulse sind eigentlich nie länger als 2,5ms.
Mit 3,6864 MHz und Prescale=1 läuft der 16-Bit-Timer z.B. nach ca. 18ms über - ein idealer Wert!
Code:
$Crystal=3686400
Dim Impuls(3) as Word
Dim N as Byte
N=1
Config timer1=Timer, prescale = 1
on timer1 Synchronisationsimpuls 'ISR bei Timer-Overflow
Enable timer1
Config IntX = Change
On IntX Flanke 'ISR bei Flankenwechsel
Enable IntX
Enable Interrupts
Do
...
Loop 'Hier läuft Dein Hauptprogramm
Flanke:
If PinX.Y = 1 then '(PinX.Y = der Interrupt-Pin!)
start timer1
Else
Stop timer1
Impulsdauer(N) = Timer1
N=N+1
Timer1=0
End if
Return
Synchronisationsimpuls:
N=1
return
...nur so als Beispiel
Dein gesamtes Programm kann unbeeinträchtigt weiterlaufen. Die Flanken starten und stoppen den Zähl-Timer, und wenn er überläuft war der Impuls länger als 18ms, so dass die Zählvariable N einfach nur auf 1 zurückgesetzt werden muss.
Lesezeichen