Code:MODE btfss REPEAT,1 ; bit 1 a '1' for on (on/off flag) goto SET_1 ; was off so turn on btfsc REPEAT,3 ; speedo on/off flag goto BYSPD btfss REPEAT,2 ; speedometer or alarm set mode goto SET_2 ; repeat1 status same, repeat2 =1 BYSPD bcf REPEAT,1 ; if set then clear on/off flag bcf REPEAT,2 ; clear speedometer flag bcf INTCON,INTE ; clear interrupt enable for RB0 clrf PULSE_CNT ; clear pulse counter clrf TIME_CNT1 ; clear time counter 1 clrf TIME_CNT2 ; clear time counter 2 goto WAIT SET_2 bsf REPEAT,2 ; set speedometer flag goto NO_SET1 SET_1 bsf REPEAT,1 ; if clear then set on/off flag NO_SET1 bsf INTCON,INTE ; set interrupt enable for RB0 goto WAIT UP movf DISP1,w ; display1 to w register xorlw 0x05 ; compare with decimal'5' btfss STATUS,Z ; skip next instruction if Disp <9 decimal goto UP_1 ; increase display1 ; check for maximum on display movf DISP2,w ; look at display 2 xorlw 0x05 ; compare with a 5 btfss STATUS,Z ; is it 5 then check DISP3 goto DISP_UP movf DISP3,w ; look at disp3 xorlw 0x02 ; compare with a 1 btfsc STATUS,Z ; is it a 2 goto WAIT ; maximum of 255 on display so stop counting up ; digit overflow DISP_UP clrf DISP1 ; Disp value cleared as it was beyond BCD range (0-9) movf DISP2,w ; display2 value to w xorlw 0x09 ; compare with decimal'9' (H'9') btfss STATUS,Z ; skip next instruction if Disp <9 decimal goto UP_2 ; increase display2 clrf DISP2 ; Disp value cleared as it was beyond BCD range (0-9) goto UP_3 ; increase display3 UP_1 movlw 0x05 ; a 5 in the display (count by 5's) movwf DISP1 ; display1 increased goto WAIT UP_2 incf DISP2,f ; display2 increased goto WAIT UP_3 incf DISP3,f ; display3 increased goto WAIT DOWN movf DISP1,w ; display1 to w register xorlw 0x00 ; compare with decimal'0' to see if was zero btfss STATUS,Z ; skip next instruction if Disp 0 decimal goto DN_1 ; decrease display1 ; check for display minimum movf DISP2,w ; look at display 2 xorlw 0x00 ; compare with 0 btfss STATUS,Z ; goto DISP_DN ; not 0 so can count down movf DISP3,w ; look at display 3 xorlw 0x00 ; compare with 0 btfsc STATUS,Z goto WAIT ; do not decrease beyond 000 DISP_DN movlw H'05' ; place a 5 in display1 movwf DISP1 ; disp1 = 5 movf DISP2,w ; display2 value to w xorlw 0x00 ; compare with decimal'0' to see if 0 btfss STATUS,Z ; skip next instruction if Disp 0 decimal goto DN_2 ; decrease display2 movlw H'09' ; Disp value = 9 movwf DISP2 goto DN_3 ; decrease display3 DN_1 clrf DISP1 ; display1 decreased to 0 goto WAIT DN_2 decf DISP2,f ; display2 decreased goto WAIT DN_3 decf DISP3,f ; display3 decreased ; wait period (delay plus EEPROM write time) ; delay loop plus apply tone to piezo alarm as switch press acknowledgement WAIT bsf INTCON,GIE ; allow global interrupts movlw D'100' ; set delay period for repeat of value 2 delay (sets key ; acknowledge tone frequency) movwf VALUE_1 ; VALUE_1 = w movlw D'50' ; set delay period value 2 (also sets key acknowledge tone period) LOOP_1 movwf VALUE_2 ; VALUE_2 = w LOOP_2 decfsz VALUE_2,f ; decrease VALUE_2, skip if zero goto LOOP_2 btfsc PORTA,3 ; alarm output check if high or low goto CLR_T bsf PORTA,3 ; alarm out high DEC_V1 decfsz VALUE_1,f ; decrease VALUE_1, skip if zero goto LOOP_1 bsf PORTA,3 ; alarm out high goto DELTME ; delay time CLR_T bcf PORTA,3 ; alarm out low goto DEC_V1 ; more delay time DELTME movlw D'50' ; set delay period movwf VALUE_1 ; VALUE_1 = w movlw D'255' ; set delay period value 2 LP_1 movwf VALUE_2 ; VALUE_2 = w LP_2 decfsz VALUE_2,f ; decrease VALUE_2, skip if zero goto LP_2 decfsz VALUE_1,f ; decrease VALUE_1, skip if zero goto LP_1 ; EEPROM write. Store new display values in EEPROM EPWRT movlw EEPROM1 ; address for EEPROM1 movwf EEADR ; address to write movf DISP1,w ; display1 data to w call EWRITE ; EEPROM write sequence movlw EEPROM2 ; address for EEPROM2 movwf EEADR ; address for write movf DISP2,w call EWRITE movlw EEPROM3 ; address for EEPROM3 movwf EEADR ; address for write movf DISP3,w call EWRITE movlw EEPROM4 ; address for EEPROM4 movwf EEADR ; address to write to movf REPEAT,w ; repeat values (bit 0 is alarm repeat, bit 1 is on/off) call EWRITE ; when a new speed setting is selected recalculate speed equivalent value bcf INTCON,GIE ; disable interrupts call SPDEQIV ; recalculate speed equivalent value bsf INTCON,GIE ; enable interrupts goto CLOSED ; out from EEPROM write ; subroutine to write to EEPROM EWRITE bcf FLAG_1,6 ; EEPROM write repeat flag movwf TEMP_2 ; store w in temporary storage EWRIT movf TEMP_2,w ; place value in w (used for read data sequence) movwf EEDATA ; data register bcf INTCON,GIE ; disable interrupts bsf STATUS,RP0 ; select bank 1 bsf EECON1,WREN ; enable write movlw 0x55 ; place 55H in w for write sequence movwf EECON2 ; write 55H to EECON2 movlw 0xAA ; AAH to w movwf EECON2 ; write AA to EECON2 bsf EECON1,WR ; set WR bit and begin write sequence bsf INTCON,GIE ; enable interrupts bcf EECON1,WREN ; clear WREN bit WRITE btfsc EECON1,WR ; skip if write complete WR=0 when write complete goto WRITE ; not written yet bcf EECON1,EEIF ; clear write interrupt flag ; read EEPROM DATA and check if written correctly bsf STATUS,RP0 ; select memory bank 1 bsf EECON1,RD ; read EEPROM RD_AGN nop btfsc EECON1,RD ; skip if RD low (read complete) goto RD_AGN ; wait for low RD bcf STATUS,RP0 ; select bank 0 movf EEDATA,w ; EEPROM value in w subwf EEDATA,w ; compare read value with value stored btfsc STATUS,z ; skip if not the same return ; value correctly written btfsc FLAG_1,6 ; write repeat bit, skip if clear and rewrite return bsf FLAG_1,6 ; set repeat flag rewrite once only goto EWRIT ; rewrite as not written correctly ; wait for switch to open (must test for closed switch when RA0, RA1 and RA2 are low ; because switch will appear open at RA4 when switch pull down via RA0-RA2 is high) CLOSED bcf FLAG_1,1 ; clear flag that indicates switch closed call ON ; check for closed switch call ON ; do three times to return to original switch closure call ON ; call ON ; do again just in case missed an interrupt during call call ON ; do again just in case missed one interrupt during call btfsc FLAG_1,1 ; was switch closed goto CLOSED ; yes go to check again goto SWITCH ; switch open so out ; subroutine to wait for switch to reopen ON bcf INTCON,T0IE ; prevent multiplex update bcf FLAG_1,0 ; clear flag that indicates update interrupt for display RE_CHK btfsc PORTA,4 ; check if switch closed goto OPEN bsf FLAG_1,1 ; switch closed so set flag bsf INTCON,T0IE ; allow multiplex interrupt goto RE_CHK ; closed so check till open OPEN bcf FLAG_1,0 ; clear multiplex update flag wait for next multiplex update bsf INTCON,T0IE ; allow multiplex update FLG_TST btfss FLAG_1,0 ; is flag set indicating a new interrupt for multiplexing goto FLG_TST ; wait return ; calibrate routine CALIBRT btfss REPEAT,1 ; is on/off flag on goto WAIT ; no calibration allowed when speed alarm unit is off btfsc REPEAT,2 ; is speedometer on goto WAIT ; no calibration if speedometer mode bcf INTCON,GIE ; disable interrupts clrf PULSE_CNT ; clear pulse counter clrf TIME_CNT1 ; clear time counter 1 clrf TIME_CNT2 ; clear time counter 2 bsf FLAG_1,7 ; calibrate flag set bcf INTCON,T0IF ; clear timer interrupt flag bcf INTCON,INTF ; clear interrupt flag bsf INTCON,GIE ; allow interrupts FLG1_CK btfsc FLAG_1,7 ; wait for end of calibrate, skip if end goto FLG1_CK ; recheck flag 1 bit 7 (cleared at end of calibration) ; store new calibration count numbers in EEPROM movlw EEPROM5 ; address for EEPROM5 movwf EEADR ; address to write movf TIME_CNT3,w ; counter 3 to w call EWRITE ; EEPROM write sequence movlw EEPROM6 ; address for EEPROM6 movwf EEADR ; address to write movf TIME_CNT4,w ; counter 4 to w call EWRITE ; EEPROM write sequence goto SWITCH ; check for a new closed switch ; Subroutine to convert from 8-bit binary to 2-digit BCD (packed) ; Binary value is in BIN_0 ; Result in BCD is in BCD_0 & BCD_1. ; BCD_0 is MSB, BCD_1 is LSB BCD bcf STATUS,c ; clear carry bit movlw D'8' movwf CNT_8 ; 8 in count clrf BCD_0 clrf BCD_1 ; set BCD registers to 0 LOOPBCD rlf BIN_0,f ; shift left binary registers rlf BCD_1,f ; MSB shift left rlf BCD_0,f ; LSB shift left BCD registers decfsz CNT_8,f ; reduce count value return when 0 goto DECADJ ; continue decimal adjust return ; completed decimal to BCD operation ; subroutine decimal adjust DECADJ movlw BCD_1 ; BCD LSB address movwf FSR ; pointer for BCD1 call ADJBCD ; subroutine to adjust BCD movlw BCD_0 ; BCD MS address movwf FSR ; pointer for BCD0 call ADJBCD goto LOOPBCD ; subroutine adjust BCD ADJBCD movlw 0x03 ; w has 03 addwf INDF,w ; add 03 to BCDx register (x is 0-1) movwf TEMP ; store w btfsc TEMP,3 ; test if >7 movwf INDF ; save as LS digit movlw 0x30 ; 3 for MSbyte addwf INDF,w ; add 30 to BCDx register movwf TEMP ; store w in temp btfsc TEMP,7 ; test if >7 movwf INDF ; save as MS digit return ; end subroutine end





Bookmarks