Anyone done any assembly programming with the p18f23k22 using the CCP2 module on capture mode, I get the interrupts and increment of TMR1 but no capture value in CCPR2H/L.
Max.
Max.
Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
I could write a simple program in C and then look at the assembled code!!!
Its always very messy, but It may give you a hint!
;High priority interrupt routine.
HighIntCode:
movff FSR0H,FSR0H_SHADOW ;save FSR0H register
movff FSR0L,FSR0L_SHADOW ;save FSR0L register
btfss PIR2, CCP2IF ;check CCP2 INT
goto NextINT
btfsc PIR1, TMR1IF ;skip if TMR1 OVF
goto OverF
btfsc Flags, INTC ;skip if first capture
goto Flag2 ;second capture
clrf TMR1H
clrf TMR1L
clrf CCPR2H
clrf CCPR2L
bsf T1CON, TMR1ON ;Turn T1 on
bcf PIR1, TMR1IF ;clr INT flag
bsf Flags, INTC ;Record 1st Capture
goto EndHiInt2
Flag2: ;Second int, capture value.
btfsc PIR1, TMR1IF ;test if T1 OVF
goto OverF
movff CCPR2H, ACCbHI
movff CCPR2L, ACCbLO
bsf Flags, CAPT ;indicate capture occured
bcf PIE2, CCP2IE ;turn off CCP2 int
bcf TMR1, TMR1ON ;turn off TMR1
goto EndHighInt1
NextINT:
nop ;Place other Hi Priority int here
; bra Iserv ;if so, go get timing pulses
;can do special error handling here - an unexpected interrupt occurred
OverF:
bcf Flags, INTC
bcf Flags, CAPT
EndHighInt1:
bcf PIR1, TMR1IF ;Clear T1 Int
bcf Flags, INTC
EndHiInt2:
bcf PIR2, CCP2IF ;Clr CCP2 INT
movff FSR0L_SHADOW, FSR0L ;restore FSR0L register
movff FSR0H_SHADOW, FSR0H ;restore FSR0H register
retfie FAST ;return and restore context
Setup:
bcf INTCON, GIE ;disable global interrupts
bcf INTCON, PEIE ;disable peripheral interrupts (enable for USART)
bcf PIE1, TMR1IE ;disable timer 1 interrupts
bcf PIE2, CCP2IE ;disable CCP2 interrupts
bcf PIR1, TMR1IF ;clear TMR1 interrupt flag
bcf PIR2, CCP2IF ;Clr CCP2 int Flag
clrf WREG
movff WREG, ANSELA ;set all ports I/O
movff WREG, ANSELB
movff WREG, ANSELC
bsf TRISB, CCP2_PORTB ;set CCP2 input
movlw 0x05
movwf CCP2CON ;set every rising edge cap
clrf CCPR2H ;clear registers
clrf CCPR2L
clrf CCPTMRS0 ;Set for tmr 1
; movlw
bsf RCON, IPEN ;enable priority int
;----
clrf Flags
; incf Flags
movlw 0xbe ;tmr1 prescaler /8 and TMR1 off,
movwf T1CON ;and 32khz clk
clrf TMR1H ;clear timer 1 high
clrf TMR1L ;clear timer 1 low
; clrf PORTA ;Sst PORTA for I/O
bcf ADCON0, 0 ;Set ADCON0 off
movlw 0x0f
bsf INTCON, GIE
bsf PIE2, CCP2IE ;enable CCP2 interrupts
return
;
1: #include <stdio.h>
2: #include <p18f23k22.h>
3:
4: #pragma config WDTEN = OFF
5: #pragma config LVP = OFF
6: #pragma config FOSC = XT
7:
8: void InterruptHandlerHigh (void);
9:
10: void main()
11: {
12:
13: TRISE = 0;
00AC 6A96 CLRF 0xf96, ACCESS
14: TRISB =0xff;
00AE 6893 SETF 0xf93, ACCESS
15: TRISC = 255;
00B0 6894 SETF 0xf94, ACCESS
16: PIE2bits.CCP2IE = 1; // CCP2 interrupt on
00B2 80A0 BSF 0xfa0, 0, ACCESS
17: PIR2bits.CCP2IF = 0;
00B4 90A1 BCF 0xfa1, 0, ACCESS
18: CCPTMRS0 = 0; // use timer 1
00B6 010F MOVLB 0xf
00B8 6B49 CLRF 0x49, BANKED
19: CCP2CON = 5; // every rising edge
00BA 0E05 MOVLW 0x5
00BC 6E66 MOVWF 0xf66, ACCESS
20: T1CONbits.T1RD16 = 1; // 16 bit mode
00BE 82CD BSF 0xfcd, 0x1, ACCESS
21: T1CONbits.TMR1ON = 1; // timer 1
00C0 80CD BSF 0xfcd, 0, ACCESS
22: PIE1bits.TMR1IE = 1; // timer interrupt on
00C2 809D BSF 0xf9d, 0, ACCESS
23: INTCONbits.PEIE = 1;
00C4 8CF2 BSF 0xff2, 0x6, ACCESS
24: INTCONbits.GIE = 1; // off we go
00C6 8EF2 BSF 0xff2, 0x7, ACCESS
25:
26: for(;;)
00C8 D7FF BRA 0xc8
27: {
28: }
29: }
00CA 0012 RETURN 0
30:
31: #pragma code InterruptVectorHigh = 0x08
32:
33: void
34: InterruptVectorHigh (void)
35: {
36: _asm
37: goto InterruptHandlerHigh //jump to interrupt routine
0008 EF66 GOTO 0xcc
000A F000 NOP
38: _endasm
39: }
000C 0012 RETURN 0
40:
41: #pragma code
42: #pragma interrupt InterruptHandlerHigh
43:
44: void InterruptHandlerHigh ()
00CC CFDA MOVFF 0xfda, 0xfe4
00CE FFE4 NOP
00D0 CFE2 MOVFF 0xfe2, 0xfda
00D2 FFDA NOP
00D4 52E6 MOVF 0xfe6, F, ACCESS
45: {
46: if(PIR2bits.CCP2IF) // capture!!!
00D6 B0A1 BTFSC 0xfa1, 0, ACCESS
47: {
48: PIR2bits.CCP2IF = 0; // CCP pair are loaded
00D8 90A1 BCF 0xfa1, 0, ACCESS
49: }
50: if(PIR1bits.TMR1IF) // timer overrun!!
00DA B09E BTFSC 0xf9e, 0, ACCESS
51: {
52: PIR1bits.TMR1IF = 0;
00DC 909E BCF 0xf9e, 0, ACCESS
53: }
54: }
00DE 52E5 MOVF 0xfe5, F, ACCESS
00E0 CFE5 MOVFF 0xfe5, 0xfda
00E2 FFDA NOP
00E4 0011 RETFIE 0x1
#include <stdio.h>
#include <p18f23k22.h>
#pragma config WDTEN = OFF
#pragma config LVP = OFF
#pragma config FOSC = XT
void InterruptHandlerHigh (void);
void main()
{
TRISE = 0;
TRISB =0xff;
TRISC = 255;
PIE2bits.CCP2IE = 1; // CCP2 interrupt on
PIR2bits.CCP2IF = 0;
CCPTMRS0 = 0; // use timer 1
CCP2CON = 5; // every rising edge
T1CONbits.T1RD16 = 1; // 16 bit mode
T1CONbits.TMR1ON = 1; // timer 1
PIE1bits.TMR1IE = 1; // timer interrupt on
INTCONbits.PEIE = 1;
INTCONbits.GIE = 1; // off we go
for(;;)
{
}
}
#pragma code InterruptVectorHigh = 0x08
void
InterruptVectorHigh (void)
{
_asm
goto InterruptHandlerHigh //jump to interrupt routine
_endasm
}
#pragma code
#pragma interrupt InterruptHandlerHigh
void InterruptHandlerHigh ()
{
if(PIR2bits.CCP2IF) // capture!!!
{
PIR2bits.CCP2IF = 0; // CCP pair are loaded
}
if(PIR1bits.TMR1IF) // timer overrun!!
{
PIR1bits.TMR1IF = 0;
}
}
Is this because of the 16 bit read issue?When using capture the TMR1H isn't directly available..
Controller = 12F683
Oscillator = internal at 8 MHz
bsf T1CON,TMR1ON ;turn TMR1 on
Start
movlw b'00000101' ;
movwf CCP1CON ;CCP1 rising edge capture |B0
clrf TMR1H
clrf TMR1L
_Data ;TMR1 runs continuously |B0
bcf PIR1,CCP1IF ;flag must be cleared after mode change |B0
btfss PIR1,CCP1IF ;test CCP1 interrupt flag (interrupt not enabled)
goto $-1
movf CCPR1H,w ;start time high byte
movwf CCP_T1H ;save value in shadow register
movf CCPR1L,w ;start time low byte
movwf CCP_T1L ;save value in shadow register
bcf CCP1CON,0 ;change interrupt flag to falling edge
bcf PIR1,CCP1IF ;clear flag
btfss PIR1,CCP1IF ;test CCP1 falling edge interrupt flag
goto $-1
movf CCPR1H,w ;stop time high byte
movwf CCP_T2H ;save value in shadow register
movf CCPR1L,w ;stop time low byte
movwf CCP_T2L ;save value in shadow register
bsf CCP1CON,0 ;change interrupt flag to rising edge
bcf PIR1,CCP1IF ;clear flag
call Calc_hi ;uncommented 01.23.14
btfss PIR1,CCP1IF ;test for rising edge (end of period)
goto $-1
movf CCPR1H,w ;start time high byte
movwf CCP_T3H ;save value in shadow register
movf CCPR1L,w ;start time low byte
movwf CCP_T3L ;save value in shadow register
; bcf CCP1CON,0 ;change interrupt flag to falling edge
; bcf PIR1,CCP1IF ;clear flag
; bcf T1CON, TMR1ON ;stop TMR1
; call Calc_hi ;commented 1.23.14 uncomment 1.24,commented
call Calc_tot
goto Start
;**************************************************************************************
;Subtraction
;Source: Rudy Wieser, PicList
;"Source" number to be subtracted
;"Dest" number to be subtracted from
;Result goes to Dest, Source is preserved, Carry is valid, Z flag is not valid
;CCP_T2L:H - CCP_T1L:H --> CCP_T2L:H = high period
;CCP_T3L:H - CCP_T1L:H --> CCP_T3L:H = total period
;**************************************************************************************
Calc_hi
movf CCP_T1L,w ;SourceL,w
subwf CCP_T2L ;DestL
movf CCP_T1H,w ;SourceH,w
btfss STATUS,C ;STATUS,0
incfsz CCP_T1H,w ;SourceH,w
subwf CCP_T2H ;DestH
call Out232H
retlw 0
Calc_tot
movf CCP_T1L,w ;SourceL,w
subwf CCP_T3L ;DestL
movf CCP_T1H,w ;SourceH,w
btfss STATUS,C
incfsz CCP_T1H,w ;SourceH,w
subwf CCP_T3H ;DestH
call Out232T
retlw 0
movlw 0xbe ;tmr1 prescaler /8 and TMR1 off,
movwf T1CON ;and 32khz clk
You are using the dedicated internal 32KHz clock for TMR1 source, right?
John