;****************************************************************** ;* WRITTEN BY John Morton * ;* DATE 15 / 11 / 96 * ;* COPYRIGHT P.D. * ;* VERSION 1.0 * ;* * ;* DEVICE The device monitors UV levels on certain * ;* materials used in buildings, giving a * ;* current UV reading, and a total taken over* ;* a period of time. Material type is taken * ;* into account. * ;****************************************************************** list P=16C71 include "c:\picstart\p16cxx.inc" ;=================================================================== ; Declarations: ;============== porta equ 05 portb equ 06 portc equ 07 MatType equ 23 Calib equ 24 Curr1 equ 0C Curr10 equ 11 Current equ 12 CalibPres equ 13 General equ 14 DisplayVal1 equ 15 DisplayVal10 equ 19 _84 equ 16 Calibrator1 equ 17 Calibrator2 equ 18 Calibrator1temp equ 1A Calibrator2temp equ 1B ADREStemp equ 1C dis10 equ 1E _30 equ 1F W_TEMP equ 20 STATUS_TEMP equ 21 _255 equ 22 MatTypetemp equ 25 BounceCount equ 26 ENDReg equ 7F ;=================================================== ;Bit settings : ;============== #define uv 05, 0 #define material 05, 3 #define optype 05, 2 #define buzzer 05, 3 #define dig10 05, 1 #define dig1 05, 4 #define power 06, 0 #define MatCheck 14, 1 #define MatFirst 14, 2 #define _3SecWait 14, 4 #define Off 14, 5 #define BounceWait 14, 0 #define QuickDis 14, 3 #define bouncer 14, 6 ;=================================================================== org 0 b Start ;================================================================== ; Subroutines: ;============= ;================================================================== Init ; initialises registers ;================================================================== ;=========== ; INTERRUPTS ;=========== bcf STATUS, RP0 ; makes sure in bank 0 nop ; makes space for isr b Init+4 ; b isr ; movlw b'01010000' ; enables analogue, and INT movwf INTCON ; interrupts ; global interrupt is disabled ;====== ; PORTS ;====== clrf porta ; clears porta clrf portb ; clears portb bsf STATUS, RP0 ; switches to bank 1 so that ADCON1, OPTION, ; TRISA and TRISB can be modified movlw b'00001101' movwf TRISA ; PORTA movlw b'00000000' ; PORTB movwf TRISB ;======= ; TIMING ;======= movlw b'01000111' ; sets up TMR0 movwf OPTION_REG ; ;========= ; ANALOGUE ;========= movlw b'00000010' movwf ADCON1 ; RA0 and RA1 are analogue ; inputs bcf STATUS, RP0 ; switches back to bank 0 movlw b'11000001' ; sets analogue clock, pin, movwf ADCON0 ; and enables AD conversion ;================= ; clears registers ;================= movlw 0x0C ; first user register on PIC71 movwf FSR clrloop clrf INDF incf FSR, f movlw ENDReg ; blank all user registers subwf FSR, w btfss STATUS, Z b clrloop ;================== ; sets up registers ;================== movlw .9 ; movwf DisplayVal1 ; movwf DisplayVal10 movlw .30 ; movwf _30 ; movlw .84 ; movwf _84 ; movlw .255 movwf _255 movlw 15 ; makes sures displaying time movwf FSR ; left movfw DisplayVal10 ; movwf dis10 ; movlw .1 movwf MatTypetemp movlw .6 movwf BounceCount ;*************************** ;TEMPORARY SETUP FOR TESTING ;*************************** movlw .1 movwf Calibrator1temp movwf Calibrator2temp movwf Calibrator1 movwf Calibrator2 retlw 0 ; Initialisation complete ;=================================================================================== ;=================================================================================== ;====================== ;Interrupt subroutine : ;====================== isr ;========================================================================= ; saves working and status file registers movwf W_TEMP ; copies w into w temp swapf STATUS, w ; swaps status into w movwf STATUS_TEMP ; copies into status temp ;========================================================================= btfsc ADCON0, 1 ; checks to see if it has ; finished AD conversion b ADFinish ; has finished btfsc INTCON, 1 ; checks to see if interrupted ; by INT pin b PowerPress ; power button pressed btfss INTCON, 2 ; checks to see if interrupted b ISReturn ; returns ; by TMR0 overflow ;================================================================================= ; TMRInterrupt : Debouncer / 3 Second Waiter : ;================================================== bcf INTCON, 2 ; clears TMR flag btfsc _3SecWait ; determines why it's here b Has3SecPassed ; it is waiting 3 secomds ; it is a debouncer bcf BounceWait ; bsf INTCON, 4 ; reacts to Power button bcf INTCON, 1 decfsz BounceCount b ISReturn ; returns bsf bouncer movlw .6 movwf BounceCount ; b ISReturn Has3SecPassed decfsz _30, f ; b ISReturn movlw .30 ; updates reg. _30 movwf _30 ; bcf _3SecWait ; b ISReturn ; returns ;=========================================================================== ;=========================================================================== PowerPress ;========= btfsc MatCheck ; is material button pressed ; as well. b Calibration ; changes calibration type movlw .11 ; tens digit is - movwf dis10 ; movlw 1Eh ; ones digit is tens digit movwf FSR ; which is - movlw b'10100000' ; enables only TMR and global movwf INTCON ; interrupts bsf _3SecWait ; begins a test for 3 secs. PauseLoop call Display ; keeps displaying while paused btfss power ; paused, waits for on button b UnPause ; returns btfsc _3SecWait ; has it been pressed for 3 secs? b PauseLoop ; no, keeps looping bsf Off ; yes restarts and turns off clrf porta OffLoop bsf _3SecWait ; waits another 3 seconds btfsc _3SecWait b OffLoop+1 clrf INTCON ; disables everything b ISReturn ; returns UnPause bcf INTCON, 5 call Display btfsc optype ; call OpType ; btfss optype call Dasher btfss power b UnPause+1 bcf dig10 btfsc power b UnPause+9 clrf TMR0 movlw b'01100000' movwf INTCON bsf QuickDis ; b ISReturn ; ;=========================================================================== Calibration ;========== b Calibration+6 ; button has been pressed incf Calib, f ; changes material type movlw .10 subwf Calib, w ; has it reached 10? btfsc STATUS, Z ; clrf Calib ; movlw .10 ; 10s dig is : C movwf dis10 ; movlw 24 ; 1s dig is Calib movwf FSR ; ;=========== PowerWait call Display btfsc power ; waits for power release b PowerWait ; movlw b'00100000' ; enables TMR and global movwf INTCON ; disables INT interrupt btfss INTCON, 2 ; after it overflows it will b PowerWait+5 ; disable itself bcf INTCON, 5 ; btfsc power ; waits for power to be b Calibration+1 ; pressed btfss material ; waits for material release b CalibTimeLoop ; call Display ; b PowerWait+7 ; keeps testing ;============ CalibTimeLoop movfw ADRES movwf CalibPres bcf STATUS, C ; divides value by 8 rrf CalibPres, f ; bcf STATUS, C ; rrf CalibPres, f ; bcf STATUS, C ; rrf CalibPres, f ; ; What is 256 divided by CalibPres ? clrf Calibrator1 movfw CalibPres btfss STATUS, Z b CalibFind+1 movlw .1 movwf Calibrator1 b CalibFind+5 CalibFind incf Calibrator1, f movfw CalibPres ; addwf CalibPres, f ; btfss STATUS, C ; b CalibFind movfw Calib ; call CalibScale movwf Calibrator2 ; updates real and temp movwf Calibrator2temp ; file regs. movfw Calibrator1 ; updates temp file reg. movwf Calibrator1temp ; b ISReturn ; returns ;========= CalibScale addwf PCL, f ; retlw .1 retlw .2 retlw .3 retlw .4 retlw .8 retlw .12 retlw .16 retlw .24 retlw .32 ;=========================================================================== ;=========================================================================== ADFinish ;======= bcf ADCON0, 1 ; resets AD converter movfw ADRES movwf Current ; subwf _255, w movwf ADREStemp ; bcf STATUS, C ; divides current by two rrf Current, f ; clrf Curr10 b SplitUp+1 SplitUp incf Curr10, f ; movlw .10 ; subwf Current, f ; btfsc STATUS, C ; b SplitUp ; movlw .10 ; addwf Current, w ; movwf Curr1 movlw .10 subwf Curr10, w btfss STATUS, C b ISReturn ; returns movlw .9 movwf Curr10 movwf Curr1 b ISReturn ;========================================================================= ; reloads working and status file registers ISReturn swapf STATUS_TEMP, w ; swaps status temp into w movwf STATUS ; copies into status swapf W_TEMP, f ; swaps w temp swapf W_TEMP, w ; swaps w temp into w retfie ; returns ;=========================================================================== ;================== END OF ISR ==================== ;=========================================================================== ;=========================================================================== Display ;====== btfss TMR0, 0 ; selects appropriate digit b Digit1 ; b Digit10 ; Digit10 movfw dis10 ; call _7Seg ; movwf portb ; bcf dig1 bsf dig10 ; return ; Digit1 movfw INDF ; call _7Seg ; movwf portb ; bcf dig10 ; bsf dig1 return ; _7Seg addwf PCL, f ; 0-9, 10 is C, 11 is - retlw b'01111110' retlw b'00001100' retlw b'10110110' retlw b'10011110' retlw b'11001100' retlw b'11011010' retlw b'11111010' retlw b'01001110' retlw b'11111110' retlw b'11011110' retlw b'01110010' retlw b'10000000' ;=========================================================================== TimeCheck ;======== ;=========================================== ; Uses magic scaler number to correct values movfw _84 ; scales time subwf TMR0, w ; btfss STATUS, Z ; return ; NO btfss QuickDis ; b Nextime movlw 15 movwf FSR movfw DisplayVal10 movwf dis10 ;=============================== ; Uses UV reading to affect time Nextime movlw .84 ; updates main scaler reg. addwf _84, f ; decfsz ADREStemp, f ; compares with UV reading return ; ;====================================== ; resets certain other changing factors movlw 15 ; makes sures displaying time movwf FSR ; left movfw DisplayVal10 ; movwf dis10 ; bcf MatFirst ; resets other bits bsf ADCON0, 2 ; starts new AD result ;=========================================== ; adjusts according to material type decfsz MatTypetemp, f ; compares with material type return ; incf MatType, w ; updates temp reg. movwf MatTypetemp ;=========================================== ; adjusts according to two calibration regs. decfsz Calibrator1temp, f ; compares with 1st calibrator return ; movfw Calibrator1 ; updates temp file reg. movwf Calibrator1temp ; decfsz Calibrator2temp, f ; compares with 2nd calibrator return ; movfw Calibrator2 ; updates temp file reg. movwf Calibrator2temp ; ;=========================================== ; changes displaying value (units then tens) decf DisplayVal1, f ; changes display value btfss DisplayVal1, 7 ; has it gone lower than 0? return ; NO movlw .9 ; resets DisplayVal1 movwf DisplayVal1 ; decf DisplayVal10, f ; movfw DisplayVal10 movwf dis10 btfss DisplayVal10, 7 ; return bsf STATUS, 5 ; bank 1 bcf buzzer ; RA3 output bcf STATUS, 5 ; bank0 bsf buzzer ; ;============================================ ; does nothing for three seconds Wait3Secs bsf INTCON, 5 bsf _3SecWait ; tells isr that this is ; a 3 second wait btfsc _3SecWait ; isr will clear this bit b Wait3Secs+2 ; when it has finished bcf buzzer ; turns off buzzer b Start ; resets ;=========================================================================== OpType ;===== movfw Curr10 ; 10s dig is current 10s UV val movwf dis10 ; movlw 0C ; 1s dig is current 1s UV val movwf FSR ; bsf QuickDis return ; ;=================================================================== Dasher ;===== movlw .11 ; tens digit is - movwf dis10 ; movlw 1Eh ; ones digit is tens digit movwf FSR ; which is - return ;======================================================================= ;======================================================================= ; START ;====== Start call Init ; sets up everything ;sleep ; tilt switch is off, sleeps ; woken up by INT pin bsf INTCON, 7 ; enables global interrupt ;========================================================================= ;========================================================================= Main ;=== bsf ADCON0, 2 ; starts conversion btfsc Off ; tests whether or not it should b Start ; reset and sleep btfsc optype ; call OpType ; call Display call TimeCheck ; counts down according to ; ADRES btfss bouncer b Cont btfss material ; is it still pressed b Cont bcf MatCheck ; no bcf bouncer ; Cont btfss MatCheck ; should it check for button b MaterialCheck ; it is able to check btfsc porta, 3 ; debounce sequence b MatChange+5 ; btfsc BounceWait b Main+1 clrf TMR0 bcf INTCON, 2 bsf INTCON, 5 ; enables TMR0 interrupt bsf BounceWait b Main+1 MaterialCheck btfsc material ; checks for material button b MatChange ; b Main+1 ; MatChange btfss MatFirst ; is this the first time its been pressed b MatChange+5 ; for a while incf MatType, f ; changes material type btfsc MatType, 3 ; has it reached 8? clrf MatType ; movlw .11 ; 10s dig is : - movwf dis10 ; movlw 23 ; 1s dig is MatType movwf FSR ; bsf MatCheck ; doesn't check for a while bsf MatFirst ; bcf QuickDis ; incf MatType, w movwf MatTypetemp b Main+1 END