Mosaic
Well-Known Member
I wanted to get a bit of feedback on this approach, thx for reading.
Constraints
1) 16F886 @ 8 Mhz
2) CCP/ECCP pins not available
3) T0CK available
4) TMR1 (16 bit) running at 2Mhz Fosc.
5) External Pulse period around 2000 µS.
6) Pulse width from 5 µS to 300 µS
7) External Pulse period NOT synced to Fosc.
8) Accuracy desired : ±1µS
9) Interrupt processing overhead: 30µS
Possible Solution
Preset TMR0 (setup as counter) to 255, rising edge triggered as the external pulse input.
Pulse #1 T0IF (rising edge) interrupt servicing:
a) the TMR1L & TMR1H bytes are buffered as 'Time1' word.
b) T0SE set to falling edge and TMR0 reset to 255, T0IF cleared just before RETFIE.
Pulse#2 (falling edge) T0IF servicing:
a) If this 'Time2' - Time1 is < 400µS then Pulse Width = Time2-Time1.
b)Otherwise sample NEXT rising edge and calc. for Pulse Width.Can set a 'flag' to note this condition.
Within current T0IF servicing, reset T0SE to rising edge, Tmr0 to 255, clrf T0IF and RETFIE
Pulse#3 (rising edge) T0IF servicing
a)based on pulse#2 'flag' set, Pulse width = Time2-{(Time3+Time1)/2}
b) if 'flag' clear then Pulse width was obtained in Pulse#2 and the loop repeats as the Pulse#3 setup ≡ Pulse#1 setup
EDIT:
Conclusion:
For those interested, the reliable solution required transferring TMR1 duties to TMR2 and utilising the T1 Gate feature coupled with a falling edge T0CK interrupt to obtain automated updates of the most recent pulse width. Both PWM channels remain available as no capture event was required.
Constraints
1) 16F886 @ 8 Mhz
2) CCP/ECCP pins not available
3) T0CK available
4) TMR1 (16 bit) running at 2Mhz Fosc.
5) External Pulse period around 2000 µS.
6) Pulse width from 5 µS to 300 µS
7) External Pulse period NOT synced to Fosc.
8) Accuracy desired : ±1µS
9) Interrupt processing overhead: 30µS
Possible Solution
Preset TMR0 (setup as counter) to 255, rising edge triggered as the external pulse input.
Pulse #1 T0IF (rising edge) interrupt servicing:
a) the TMR1L & TMR1H bytes are buffered as 'Time1' word.
b) T0SE set to falling edge and TMR0 reset to 255, T0IF cleared just before RETFIE.
Pulse#2 (falling edge) T0IF servicing:
a) If this 'Time2' - Time1 is < 400µS then Pulse Width = Time2-Time1.
b)Otherwise sample NEXT rising edge and calc. for Pulse Width.Can set a 'flag' to note this condition.
Within current T0IF servicing, reset T0SE to rising edge, Tmr0 to 255, clrf T0IF and RETFIE
Pulse#3 (rising edge) T0IF servicing
a)based on pulse#2 'flag' set, Pulse width = Time2-{(Time3+Time1)/2}
b) if 'flag' clear then Pulse width was obtained in Pulse#2 and the loop repeats as the Pulse#3 setup ≡ Pulse#1 setup
EDIT:
Conclusion:
For those interested, the reliable solution required transferring TMR1 duties to TMR2 and utilising the T1 Gate feature coupled with a falling edge T0CK interrupt to obtain automated updates of the most recent pulse width. Both PWM channels remain available as no capture event was required.
Last edited: