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.


Menu

Re: Has anyone tried AI with PICBASIC
What I figured by myself and what actually helps is when asking AI to write picbasic pro code, if you specify write code for "PicBasic Pro 3", not only "PicBasic Pro", it will make far less errors in...
CuriousOne Yesterday, 10:07