I am trying to do 16 bit PWM as per Tip#10 16 bit Resolution PWM page 40 (3-10) Microchip Tips 'n Tricks
Basically when TM1 value equals the CCP1 (PWM duty) setting the CCP1 interrupt sets PORTC.2 low (works OK).
When the free running TM1 interrupts it is supposed to set PORTC.2 high (doesn't).
As a test CCP1 can be configured to toggle (this works OK as see in ISIS) but if configured
to set low for PWM the pin cannot be set high again even though CCP1 int is cleared.
The following code tries to set pin high in TM1 interrupt.
Norm
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
Clear
sSEROUT_PIN VAR PORTA.2
sBAUD CON 16416 '16416 = 19200 BAUD
wsave VAR BYTE bankA system ' Saves W
ssave VAR BYTE bankA system ' Saves STATUS
yTEMP VAR Byte
wDUTY VAR Word
wDUTY = 32768 '32768 = 50% DUTY PWM
'********************
'16 BIT CCP1 PWM
Input PORTC.2 ' Disable the HPWM output while things are being setup
RCON.7 = 0 ' 0 DISABLES PRIORITY LEVELS ON INTERRUPTS (16F COMPATABILITY)
T1CON = %10110000 ' Turn off Timer1 with a Prescaler value of 1:8
PIE1 = %00000101 ' enable CCP1, TMR1 overflow interrupt
INTCON = %11000000 ' enable global and peripheral interrupts
Output PORTC.2 ' Set PORTC.2 (CCP1) to output
' CCP1CON = %00000010 'TOGGLE PORTC.2 ON MATCH TM1 WITH DUTY ********** OK ************
CCP1CON = %00001001 'LOW PORTC.2 ON MATCH TM1 WITH DUTY ?????????? NOT OK ???????????????
T3CON = %00000000
' CCPR1L = wDUTY.LOWBYTE
CCPR1H = wDUTY.HighByte
CCPR1L = wDUTY.LowByte
DEFINE INTHAND myint
Goto START 'Jump over the subroutines
'**** ASSEMBLY INTURRUPT ROUTINE ****
Asm
myint ;KEEP LEFT
; Save the state of critical registers
movwf wsave ; Save W
swapf STATUS, W ; Swap STATUS To W (swap avoids changing STATUS)
clrf STATUS ; Clear STATUS
movwf ssave ; Save swapped STATUS
EndAsm
' yTEMP = yTEMP +1
' SerOut2 sSEROUT_PIN,sBAUD,["INT ",DEC yTEMP,13]
PIR1.2 = 0 ' CLEAR THE CCP1 INT FLAG
High PORTC.2 '???????????????? DOES NOT SET HIGH ?????????????????
Asm
bcf PIR1, 0 ; Clear interrupt flag
swapf ssave, W ; Retrieve the swapped STATUS value (swap To avoid changing STATUS)
movwf STATUS ; Restore it To STATUS
swapf wsave, F ; Swap the stored W value
swapf wsave, W ; Restore it To W (swap To avoid changing STATUS)
retfie ; Return from interrupt
EndAsm
'**** END ASSEMBLY INTURRUPT ROUTINE ****
'***********************************************
'***********************************************
START:
PAUSE 800
SerOut2 sSEROUT_PIN,sBAUD,["START",13]
T1CON.0 = 1 'TMR1 ON
MAIN:
yTEMP = yTEMP +1
SerOut2 sSEROUT_PIN,sBAUD,["LOOP ",Dec yTEMP,13]
PAUSE 500
Goto MAIN
End
Bookmarks