I can successfully get CCP1 to work and display the measured period on an LCD using Timer 1, but adding CCP2 using Timer 3 does not work. It never interrupts and jumps to CCP2_INT. Pretty sure this has something to do with setting up 2 priority interrupts, but haven't found the problem. Anyone have some insight?
Code:
'PIC18F4620 CCP1 & CCP2 test
OSCCON=%01110000 ' SET TO 8 MHZ internal oscillator
DEFINE OSC 08 ' 8MHZ clock speed
DEFINE INTHAND CCP_INT ' Declare high-pri interrupt handler
ADCON1 = 15 ' All digital
CMCON = 7 ' Turns off comparators
define LCD_COMMANDUS 1500 ' set command delay in us
define LCD_DATAUS 50 ' set data delay in us
define LCD_DREG PORTD ' set LCD data port
define LCD_DBIT 4 ' set LCD starting data bit
define LCD_RSREG PORTD ' define RS port
define LCD_RSBIT 2 ' define RS bit
define LCD_EREG PORTD ' set LCD ENABLE port
define LCD_EBIT 3 ' set LCD ENABLE bit
define LCD_BITS 4 ' set LCD bits 4 or 8
define LCD_LINES 2 ' set # of LCD rows 2 or 4
'*******************************************************************************
'************************** V A R S / C O N S ********************************
'*******************************************************************************
'CCP1 INTERRUPT
Symbol Capture = PIR1.2 ' CCP1 capture flag
SYMBOL CapIE = PIE1.2 ' CCP1 interrupt enable bit
SYMBOL CapPriEn = IPR1.2 ' priority enable bit for CCP1 interrupt
SYMBOL PriEnable = RCON.7 ' set to enable priority levels on interrupts
_T1 VAR WORD BANKA SYSTEM ' 1st capture value
PW VAR WORD BANKA SYSTEM ' 2nd capture value & ultimately final pulse width
CF VAR BYTE BANKA SYSTEM ' indicates when last capture is ready
Period var word
'CCP2 INTERRUPT
Symbol Capture2 = PIR2.2 ' CCP2 capture flag
SYMBOL CapIE2 = PIE2.2 ' CCP2 interrupt enable bit
SYMBOL CapPriEn2 = IPR2.2 ' priority enable bit for CCP2 interrupt
SYMBOL PriEnable2 = RCON.7 ' set to enable priority levels on interrupts
_T2 VAR WORD BANKA SYSTEM ' 1st capture value
PW2 VAR WORD BANKA SYSTEM ' 2nd capture value & ultimately final pulse width
CF2 VAR BYTE BANKA SYSTEM ' indicates when last capture is ready
Period2 var word
'CONFIGURE DISPLAY
pause 100
ln1 con $80
ln2 con $C0
CS con 1
pause 500
LCDOUT $FE,CS
CLEAR ' clear RAM on POR
TRISC.2 = 1 ' CCP1 input pin (Capture1 input on 18F4620)
TRISC.1 = 1 ' CCP2 input pin (Capture2 input on 18F4620)
INTCON = 0 ' Interrupts off for now
pause 1000 'add bootup delay to allow things to settle
GOTO start 'jump over interrupt handler
ASM
CCP_INT
BTFSS CCP1CON,0 ; capture from rising edge?
BRA Fall ; no .. goto falling edge
MOVFF CCPR1L, _T1 ; get low capture byte into _T1
MOVFF CCPR1H, _T1+1 ; get high capture byte into _T1
BRA IntExit ; outta here
Fall
MOVFF CCPR1L, PW ; get low capture byte into PW
MOVFF CCPR1H, PW+1 ; get high capture byte into PW
BSF CF,0 ; indicate last capture
IntExit
BTG CCP1CON,0 ; toggle between rising/falling edge captures
BCF PIR1,2 ; clear capture interrupt flag bit
RETFIE FAST ; return/restore W, STATUS and BSR
ENDASM
ASM
CCP2_INT
BTFSS CCP2CON,0 ; capture from rising edge?
BRA Fall ; no .. goto falling edge
MOVFF CCPR2L, _T2 ; get low capture byte into _T1
MOVFF CCPR2H, _T2+1 ; get high capture byte into _T1
BRA IntExit ; outta here
Fall2
MOVFF CCPR2L, PW2 ; get low capture byte into PW
MOVFF CCPR2H, PW2+1 ; get high capture byte into PW
BSF CF2,0 ; indicate last capture
IntExit2
BTG CCP2CON,0 ; toggle between rising/falling edge captures
BCF PIR2,2 ; clear capture interrupt flag bit
RETFIE FAST ; return/restore W, STATUS and BSR
ENDASM
start:
'******************** CCP1 / Timer 1 ********************
CCP1CON = %00000111 'Capture mode, capture on 16th rising edge
T1CON.7=1 'Enable timer 16 bit `
T1CON.6=1 'Timer1 OSC
T1CON.5=1 '1:8 prescaler
T1CON.4=1 '1:8 prescaler
T1CON.3=0 'Timer1 OSC off
T1CON.2=0 'sychro clock
T1CON.1=0 'Internal clock
TMR1H = 0 'Clear high byte of TMR1 counter
TMR1L = 0 'Clear low byte
PriEnable = 1 'Enable priority levels on interrupts
Capture = 0 'Clear capture flag bit
CapPriEn = 1 'Set CCP1 int to high priority
CapIE = 1 'Enable the CCP1 capture interrupt
INTCON = %11000000 'Global + peripheral ints enabled
T1CON.0 = 1 'Turn TMR1 on here
'******************** CCP2 / Timer 3 ********************
CCP2CON = %00000111 'Capture mode, capture on 16th rising edge
T3CON.7=1 'Enable timer 16 bit `
T3CON.6=1 'Timer1 OSC
T3CON.5=1 '1:8 prescaler
T3CON.4=1 '1:8 prescaler
T3CON.3=0 'Timer 3 source
T3CON.2=0 'sychro clock
T3CON.1=0 'Internal clock
TMR3H = 0 'Clear high byte of TMR1 counter
TMR3L = 0 'Clear low byte
PriEnable2 = 1 'Enable priority levels on interrupts
Capture2 = 0 'Clear capture flag bit
CapPriEn2 = 1 'Set CCP1 int to high priority
CapIE2 = 1 'Enable the CCP1 capture interrupt
INTCON = %11000000 'Global + peripheral ints enabled
T3CON.0 = 1 'Turn TMR1 on here
goto main
'*******************************************************************************
'********************** S U B R O U T I N E S **********************************
'*******************************************************************************
getCCP1:
IF CF.0 THEN ' figure out & print result only after last capture
period = PW-_T1
CF.0 = 0 ' clear flag bit
ENDIF
return
getCCP2:
IF CF2.0 THEN ' figure out & print result only after last capture
period2 = PW2-_T2
CF2.0 = 0 ' clear flag bit
ENDIF
return
'*******************************************************************************
'********************** M A I N L O O P *************************************
'*******************************************************************************
main:
gosub getCCP1
lcdout $fe, ln1, "#1 = ", dec period, " "
gosub getCCP2
lcdout $fe, ln2, "#2 = ", dec period2, " "
goto main
end
Bookmarks