This will save you a little time deciphering it;
' Measuring signal pulse widths with capture module ' Procedure for high-going pulse: ' 1. Configure CCP to capture on rising edge ' 2. Setup Timer1 so it will not overflow during max pulse width time ' 3. Enable ccp capture ' 4. Once capture flag bit is set, save captured value as T1 ' 5. Reconfigure CCP to capture on falling edge ' 6. On 2nd capture, save 2nd value as PW ' 7. Subtract T1 from PW for the pulse width value ' Test signal: ' 12.04kHz pulse with 41uS high / 42uS low ' Input signal connected to RC2/CCP1 pin ' PIC18F242 @20MHz DEFINE OSC 20 DEFINE DEBUG_REG PORTC DEFINE DEBUG_BIT 6 DEFINE DEBUG_BAUD 115200 DEFINE DEBUG_MODE 0 ' 1 = inverted, 0 = true Symbol Capture = PIR1.2 ' CCP1 capture flag T1 VAR WORD ' 1st capture value PW VAR WORD ' 2nd capture value & ultimately final pulse width TRISC.2 = 1 ' CCP1 input pin (Capture input) INTCON = 0 ' Interrupts off ReLoad: CCP1CON = 000101 ' Capture mode, capture on rising edge T1CON = 0 ' TMR1 prescale=1, clock=Fosc/4, TMR1=off (200nS per count @20MHz) TMR1H = 0 ' Clear high byte of TMR1 counter TMR1L = 0 ' Clear low byte T1CON.0 = 1 ' Turn TMR1 on here Capture = 0 ' Clear capture int flag bit While !Capture ' Wait here until capture on rising edge Wend ' Rising edge detected / stuff Timer1 value in T1 T1.HighByte = CCPR1H T1.LowByte = CCPR1L CCP1CON.0 = 0 ' Configure capture for falling edge now Capture = 0 ' Clear capture interrupt flag bit While !Capture ' While here until capture on falling edge Wend ' Falling edge detected / stuff Timer1 value in PW PW.HighByte = CCPR1H PW.LowByte = CCPR1L PW = PW-T1 ' High pulse width = PW-T1 ' Convert to uS for 20MHz osc with 200nS Timer1 ticks PW = (PW * 2)/10 DEBUG dec PW,"uS High",13,10 ' Output to RS232 display GOTO ReLoad END
18F242 CCP1 pin. 41uS high, 42uS low.
It's spot-on. Returns 41uS High on MCS serial terminal. Fluke ScopeMeter 123
shows precisely the same timing.
Much nicer than pulsin, count, etc..
Darrel Taylors' instant interupts works perfect for this.
' PIC18F242 @20MHz DEFINE OSC 20 DEFINE DEBUG_REG PORTC DEFINE DEBUG_BIT 6 DEFINE DEBUG_BAUD 115200 DEFINE DEBUG_MODE 0 ' 1 = inverted, 0 = true OverFlows VAR BYTE ' Timer1 overflow total Remainder VAR WORD ' Remaining Timer1 ticks after falling edge capture INCLUDE "DT_INTS-18.bas" ; Base Interrupt System INCLUDE "ReEnterPBP-18.bas" ; Include if using PBP interrupts ;----[High Priority Interrupts]---------------------------------------- ASM INT_LIST macro ; IntSource, Label, Type, ResetFlag? INT_Handler CCP1_INT, _Capture, PBP, yes INT_Handler TMR1_INT, _Timer1, PBP, yes endm INT_CREATE ; Creates the High Priority interrupt processor ENDASM CCP1CON = 000101 ' Capture mode, capture on rising edge T1CON = 0 ' TMR1 prescale=1, clock=Fosc/4, TMR1=off (200nS per count @20MHz) @ INT_ENABLE CCP1_INT ; enable Capture interrupts Main: IF T1CON.0 = 0 THEN ' If done, show result DEBUG "Timer Overflows = ",DEC OverFlows DEBUG " Remaining ticks = ",dec Remainder,13,10 ENDIF PAUSE 2000 @ INT_ENABLE CCP1_INT ; Start new capture GOTO Main '---[CCP1 - interrupt handler]------------------------------------------ Capture: IF CCP1CON = 000101 THEN ' If rising edge capture then TMR1L = 0 ' Clear Timer1 counts TMR1H = 0 T1CON.0 = 1 ' Turn Timer1 on at rising edge capture OverFlows = 0 ' Clear over flow counts Remainder = 0 ' Clear remainder CCP1CON = 000100 ; Switch to falling edge capture PIR1.0 = 0 ; Clear Timer1 overflow flag before enable @ INT_ENABLE TMR1_INT ; Enable Timer 1 Interrupts GOTO OVER_CCP ; Done, exit ENDIF IF CCP1CON = 000100 THEN ; If falling edge capture then T1CON.0 = 0 ; Stop Timer1 CCP1CON = 000101 ; Switch back to rising edge capture @ INT_DISABLE TMR1_INT ; Disable Timer 1 Interrupts @ INT_DISABLE CCP1_INT ; Disable CCP1 Interrupts Remainder.LowByte = TMR1L ; Get remaining Timer1 counts on falling edge Remainder.HighByte = TMR1H ENDIF OVER_CCP: @ INT_RETURN '---[TMR1 - interrupt handler]--------------------------------------------- Timer1: OverFlows = OverFlows + 1 @ INT_RETURN END
pulse with a 5 second delay between each.
For the 30mS pulse it displays: Timer Overflows = 2 Remaining ticks = 19048
The total pulse width: (2 * 65536 * 200nS) + (19048 * 200nS) = 30.0242mS
For the 1000mS pulse: Timer Overflows = 76 Remaining ticks = 19480
So: (76 * 65536 * 200nS) + (19480 * 200nS) = 1.0000432 S
Darrels interrupt routines are pretty handy.
Re: SERIN2 Receiving Wrong Data
The sending device has the typical 18F4550 USB setup and it is set to "Define OSC 48". The receiving device is set to "DEFINE OSC 16".
rsocor01 Yesterday, 19:56