sanjubluerock3
Full Member level 3
- Joined
- Sep 29, 2008
- Messages
- 174
- Helped
- 21
- Reputation
- 42
- Reaction score
- 18
- Trophy points
- 1,298
- Location
- Bengaluru, India
- Activity points
- 2,080
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.
;************************************************************************************************
;pic12f6xx autocalibration & test program
;
;version: 1.0
;date: 10/21/02
;author: Mike rylee
;description:this program calibrates the internal rc oscillator on the pic12f6xx to the tolerance
; specified in the #define tolerance measurement parameter below. The oscillator is
; calibrated using a 5khz 50% square wave signal input on gp0 from a function generator.
; the calibration is started by pushing the pushbutton connected to gp2.
; after calibration a 5khz test signal can be output on gp5 by the pushbutton connected
; to gp1 to check the calibration.
;************************************************************************************************
list p=12f675
#include <p12f675.inc>
__config _cp_off & _cpd_off & _boden_off & _mclre_off & _wdt_off & _pwrte_on &
intrc_osc_noclkout
;general purpose registers
counter equ 0x20
;measurement parameters
#define referenceperiod .200 ;reference period in microseconds
#define tolerance .1 ;tolerance can be tweaked for oscillator accuracy
#define calibrationtime .10 ;number of times to measure signal during calibration
;main i/o
#define input0 gpio,0 ;input reference waveform of 5khz
#define input1 gpio,1 ;test button
#define input2 gpio,2 ;calibrate button
#define output gpio,5 ;outputs 5khz calibrated waveform
;eeprom definitions
#define calflagadr 0x7e ;value of 0xa5 => calibration has not been performed
;value of 0x5a => calibration has been performed
#define calvaladr 0x7f ;calibration value
;debug
#define led gpio,4 ;debug led
;************************************************************************************************
;reset vector
;************************************************************************************************
org 0x000
call 0x3ff ; retrieve factory calibration value
banksel osccal ; bank1
movwf osccal ; load osccal
goto init
;************************************************************************************************
;initialization
;************************************************************************************************
init
movlw b'00001111' ;gp0-input, gp1-input, gp2-input, gp4-output,gp5-output
movwf trisio
clrf ansel
clrf vrcon ;turn off vref
banksel gpio ;bank 0
movlw .7 ;turn off comparator
movwf cmcon
banksel option_reg ;bank 1
movlw b'01001000' ;pull ups enabled, rising edge, assigned to wdt,
;prescaler is 1:1 wdt
movwf option_reg
bsf wpu,2 ;gp2 - pullup enabled
bsf wpu,1 ;gp1 - pullup enabled
banksel gpio ;bank0
clrf gpio
;************************************************************************************************
;main program - this routine watches button input1 & input2
; - calls calibrate() or calls test()
;************************************************************************************************
main
btfss input1 ;check test button
goto one
btfsc input2 ;check calibration button
goto main
two
bsf led
call calibrate
bcf led
goto main
one
bsf led
call test
bcf led
goto main
;************************************************************************************************
;subroutines
;************************************************************************************************
;test() - this routine is used to test the osccal value in the pic12f6xx
; - checks if calibration was performed
; - updates osccal value if calibration was performed
; - outputs a 5 khz 50% square wave on output until pushbutton is released
;************************************************************************************************
test
movlw calflagadr
call eeread
sublw 0x5a
btfss status,z ;was calibration flag set?
Goto starttest ;no don't change osccal
movlw calvaladr
call eeread ;yes change the osccal
banksel osccal ;bank1
movwf osccal
banksel gpio ;bank0
starttest ;the instructions below make a 5khz 50% square wave
;output on gp1 if the device is calibrated
bsf output ;1 us
movlw .31 ;delay 99 us
call delayus ;99+1 = 100 us
bcf output ;1us
movlw .30 ;delay 96 us
call delayus
btfss input1 ;1 us
goto starttest ;2 us =>1+96+1+2 = 100 us
return
;************************************************************************************************
;calibrate()- measures a period from the input(gp0) reference signal
; - updates osccal value
; - updates e^2
;************************************************************************************************
calibrate
movlw calibrationtime
movwf counter ;calibration counter
low0
btfsc input0 ;wait to sample low edge #0 (makes sure we are
;synchronized first time through)
goto low0
high1
btfss input0 ;wait to sample high edge #1
goto high1
clrf tmr0 ;start timer (timer will be behind by 5us after this
;instruction)
low1
btfsc input0 ;wait to sample low edge #1
goto low1
high2
btfss input0
goto high2
movf tmr0,w ;stop timer (timer will be stopped 3us late)
addlw .2 ;timer is behind by 2us total from start to stop
call checkperiod ;see if osccal needs to be adjusted
low2
btfsc input0 ;wait to sample low edge #2
goto low2
decfsz counter,f ;decrement the calibration counter
goto high1
call update_ee ;update e^2
return
;************************************************************************************************
;update_ee - this routine updates calibration flag & calibration value
;************************************************************************************************
update_ee
banksel eedata ;bank1
movlw 0x5a ;update calibration flag
movwf eedata
movlw calflagadr
call eewrite
movf osccal,w
movwf eedata
movlw calvaladr
call eewrite ;update calibration value
banksel gpio ;bank0
return
;************************************************************************************************
;checkperiod(w)- this routine computes the difference between the referenceperiod and
; measuredperiod
; - the measuredperiod is contained in w when this routine is called
; - the osccal is adjusted up or down if the period is outside the specified
; tolerance
;************************************************************************************************
checkperiod
sublw referenceperiod
btfsc status,z ;if (referenceperiod - measuredperiod = 0) don't change
;osccal
return
btfsc status,c ;if (referenceperiod - measuredperiod > 0) oscillator
;could be too fast
goto runningslow ;else oscillator could be too slow
runningfast
xorlw 0xff ;two's complement value
addlw .1
sublw tolerance ;if (tolerance - (referenceperiod - measuredperiod) = 0
;don't change osccal
btfsc status,z
return
goto adjustdown ;else adjust osccal down
runningslow
sublw tolerance ;if (tolerance - (referenceperiod - measuredperiod) = 0
;don't change osccal
btfsc status,z
return
goto adjustup ;else adjust osccal up
adjustdown
banksel osccal ;bank1
movlw .4
subwf osccal,f ;adjust osccal down
banksel gpio ;bank0
return
adjustup
banksel osccal ;bank1
movlw .4
addwf osccal,f ;adjust osccal up
banksel gpio ;bank0
return
;************************************************************************************************
;eeread(w) - address to read is contained in w when this function is called
;************************************************************************************************
eeread
banksel eeadr ;bank1
movwf eeadr
bsf eecon1,rd
movf eedata,w
banksel gpio ;bank0
return
;************************************************************************************************
;eewrite(w) - address to read is contained in w when this function is called
; - eedata is loaded prior to this function call
; - bank1 must be selected before this function is called
;************************************************************************************************
eewrite
movwf eeadr
bsf eecon1,wren
bcf intcon, gie
movlw 0x55
movwf eecon2
movlw 0xaa
movwf eecon2
bsf eecon1,wr
eecomplete
btfsc eecon1,wr
goto eecomplete
bcf eecon1,wren
return
;************************************************************************************************
;************************************************************************************************
;delayus(w) - delay microseconds
; - totaltime(w) = [(1)+(2)+(1)+(w*3-1)+1+2] * (4/osc) (this includes the movlw & the
; call)
; - max time when w=0xff, [ 771 cycles * (4/osc) ]
; - must declare counter as gpr
; - w > 0
;************************************************************************************************
delayus
movwf counter
loop1
decfsz counter,f
goto loop1
nop
return
;************************************************************************************************
;eeprom - calflagadr - contains calibration flag value
; - calvaladr - contains calibration value
;************************************************************************************************
org (0x2100+calflagadr)
de 0a5h ;initialize calibration flag
de 000h ;initialize calibration value
end
Dear Padman,use this program for pic12f6xx auto-calibration & testing: