Hi Norm,
To set the pin High, simply clear the CCP1CON register, then load it<sub>(Bruce)</sub> with the compare mode again %00001001 (9).
And, only do it on a Timer1 interrupt. The CCP changes the pin low on its own, so you don't need to enable the CCP interrupt.
A few other things are either not needed or can be done differently.
Have a go at this ...
Code:
'FL PIC18F4520
; @ __CONFIG _CONFIG1H, _OSC_XT_1H
@ __CONFIG _CONFIG1H, _OSC_HSPLL_1H
@ __CONFIG _CONFIG2L, _BOREN_ON_2L
@ __CONFIG _CONFIG2H, _WDT_ON_2H
@ __CONFIG _CONFIG3H, _MCLRE_ON_3H & _PBADEN_OFF_3H
@ __CONFIG _CONFIG4L, _LVP_OFF_4L & _XINST_OFF_4L
DEFINE OSC 40
DEFINE INTHAND myint
Clear
sSEROUT_PIN VAR PORTA.2
sBAUD CON 16416 '16416 = 19200 BAUD
yTEMP VAR Byte
wDUTY VAR WORD EXT ' map wDuty to CCPR1L:H as a word
@wDUTY = CCPR1L
'***********************************************
START:
ADCON1 = $0F ' disable analog functions
CMCON = 7 ' disable comparators
'********************
'16 BIT CCP1 PWM
T1CON = %00110000 ' Turn off Timer1 with a Prescaler value of 1:8
PIE1 = %00000001 ' enable TMR1 overflow interrupt
INTCON = %11000000 ' enable global and peripheral interrupts
CCP1CON = %00001001 ' LOW PORTC.2 ON MATCH TM1 WITH DUTY
OUTPUT PORTC.2 ' Set PORTC.2 (CCP1) to output, starts High
wDUTY = 32768 ' 32768 = 50% DUTY PWM
T1CON.0 = 1 ' TMR1 ON
PAUSE 800
SerOut2 sSEROUT_PIN,sBAUD,["START",13]
'***********************************************
MAIN:
yTEMP = yTEMP +1
SerOut2 sSEROUT_PIN,sBAUD,["LOOP ",Dec yTEMP,13]
PAUSE 500
Goto MAIN
'**** ASSEMBLY INTERRUPT ROUTINE ****
Asm
myint
movlw 9 ; %00001001 compare mode, low on match
clrf CCP1CON ; clrf added per Bruce's suggestion
movwf CCP1CON ; Set Pin to default state (High)
bcf PIR1,0 ; Clear Timer Int Flag
retfie FAST ; Return from interrupt with shadow regs
EndAsm
'**** END ASSEMBLY INTURRUPT ROUTINE ****
End
P.S. Using both CCP's with this method would make a great 2 channel hardware driven servo driver.
Dutycycles between 2500-5000 would give pulses between 1-2ms at ~40hz.
Bookmarks