16F690 med intern RC osc på 8MHz. Timer1 matas av en extern 16MHz kristalloscilator. CCP är satt att göra en "capture" på varje positiv flank. Målet är helt enkelt att räkna varvtal, 10..20 000 1/min, 4 pulser/varv från en hallgivare.
Eftersom 16 bitar kan vara litet snött så hat T1 en overflowräknare i mjukvara för att klara riktigt låga varvtal.
ISR:
Kod: Markera allt
;**********************************************************************************************************
; ISR
;**********************************************************************************************************
INTERRUPT
; Keep the actual ISR as short as possible.
;
; Arrive here on any interrupt - first save the world...
;
movwf w_temp ; save off current W register contents
swapf STATUS,w ; move status register into W register
movwf status_temp ; save off contents of STATUS register
movf PCLATH,w ; move pclath register into W register
movwf pclath_temp ; save off contents of PCLATH register
movf FSR,w ; move fsr register into W register
movwf fsr_temp ; save off contents of PCLATH register
; Actual isr code, determine cause of interrupt. Most likely first
;
; This is the handler for the CCP interrupts
;
banksel PIR1
btfss PIR1,CCP1IF ; CCP fired?
goto other_int ; No, check next
BCF T1CON,TMR1ON ; Stop timer
clrf tmr1l ; Clear timer
clrf tmr1h
BSF T1CON,TMR1ON ; Start timer
movf ccpr1l,w ;
movwf count
movf ccpr1h,w ;
movwf count+1
movf t1of,w ;
movwf count+2
movf t1of+1,w ;
movwf count+3
clrf t1of ; Clear overflow
clrf t1of+1
BCF PIR1,CCP1IF ; Clear flag and continue.
;
; This is the handler for other interrupts, ie timer1
;
other_int
;banksel PIR1
btfss PIR1,TMR1IF ; If Timer 1 overflowed and caused the interrupt, handle it.
goto other_int1 ; No timer overflow
incfsz t1of,F ; Yes, increment overflow
goto other_int1
incf t1of+1
other_int1
banksel PIR1
BCF PIR1,TMR1IF ; Clear flag and continue.
;
; Catch-all for interrupt exit. Restore the world as we know it.
;
exit_interrupt
movf fsr_temp,w ; retrieve copy of FSR register
movwf fsr ; restore pre-isr FSR register contents
movf pclath_temp,w ; retrieve copy of PCLATH register
movwf PCLATH ; restore pre-isr PCLATH register contents
swapf status_temp,w ; retrieve copy of STATUS register
movwf STATUS ; restore pre-isr STATUS register contents
swapf w_temp,f
swapf w_temp,w ; restore pre-isr W register contents
retfie ; return from interrupt
;**********************************************************************************************************
; END ISR
;**********************************************************************************************************
Kod: Markera allt
; ***********************************************************************************
; START OF CODE to initialize Timer 1
; Set up Timer 1 to count every 0.5us (16MHz/8)
; This is used by the CCP to measure pulse length
;
banksel tmr1l
CLRF TMR1L ; Clear Timer1 register
CLRF TMR1H
banksel intcon
bsf INTCON,PEIE ; Enable peripheral interrupts
banksel pie1
CLRF PIE1 ; Mask all peripheral interrupts except
bsf PIE1,TMR1IE ; the timer 1 interrupts.
banksel pir1
CLRF PIR1 ; Clear peripheral interrupts Flags
movlw B'00110110' ; Set Prescale = 8, ext clock
movwf T1CON
BSF T1CON,TMR1ON ; Timer1 starts to increment
;***********************************************************************************
;END OF CODE to initialize CCP
;***********************************************************************************
; Set up CCP module
banksel CCP1CON
movlw B'00000101' ; Set up CCP as capture, every rising edge
movwf CCP1CON
banksel pie1
bsf PIE1,CCP1IE ; Enable CCP1 interrupts.
banksel intcon
bsf INTCON, GIE ; enable interrupts
Övrig kod skall inte göra så mycket. Visa på display, bryta ifall man övervarvar, samt kunna läsas från en PC bis RS-485.