3x4 Keypad Lock w
-
Upload
giselita-calderon -
Category
Documents
-
view
34 -
download
6
Transcript of 3x4 Keypad Lock w
3x4 Keypad Lock w/ 4 bit LCD
by Bert Botha [bert at itsserv,co,za]
;*************************************************************************************;Program that communicates with a keypad and displays only * to mask the number. *;This display indicates the mode that it is in. The six digit code is input and a *;calculation is done to determine if the code is correct. *;*********02/12/2003*****************15H15**********************************BJB*******
;*************************************************************************************; Setup *;************************************************************************************* LIST P=16F84A ;Processor type ERRORLEVEL -302 ;Suppress warning of bank 1 operands INCLUDE "P16F84A.INC" ;MYREG EQU 0X20 ;OUTPUT EQU 0X21 ;This reg for data reading to out pinMYREG1 EQU 0X22 ;MYREG2 EQU 0X23 ;COUNTER EQU 0X24 ;DIGITS EQU 0X25 ;FLASH1 EQU 0X28 ;DELAY2 EQU 0X29 ;DELAY3 EQU 0X2A ;COUNTER1 EQU 0X2B ;NUMBER1 EQU 0X2C ;NUMBER2 EQU 0X2D ;NUMBER3 EQU 0X2E ;NUMBER4 EQU 0X2F ;NUMBER5 EQU 0X30 ;NUMBER6 EQU 0X31 ;CODEDATA EQU 0X32 ; CLRF CODEDATA ; CLRF NUMBER1 ; CLRF NUMBER2 ; CLRF NUMBER3 ; CLRF NUMBER4 ; CLRF NUMBER5 ; CLRF NUMBER6 ; CLRF COUNTER ; CLRF OUTPUT ; CLRF MYREG ; CLRF MYREG1 ; CLRF MYREG2 ; CLRF DIGITS ; CLRF FLASH1 ;
CLRF COUNTER1 ; BSF STATUS,5 ;Select bank 1 MOVLW 0X00 ;All outputs MOVWF TRISA ;Ditto MOVLW 0X0F ;Lower nibble is inputs MOVWF TRISB ;Ditto BCF STATUS,5 ;Back to bank 0 BCF PORTB,7 ;R/S Set to zero- command mode CLRF PORTA ;Ensure all outputs are at zero GOTO START ;
;*************************************************************************************; Pinout use *;*************************************************************************************;PORTA , 0 is column 1;PORTA , 1 is column 2;PORTA , 2 is column 3;PORTB , 0 is scanning row 1;PORTB , 1 is scanning row 2;PORTB , 2 is scanning row 3;PORTB , 3 is scanning row 4 ;PORTB , 4 is clock output;PORTB , 5 is serial output pin;PORTB , 6 is enable;PORTB , 7 is R/S pin ;*************************************************************************************; Subroutines *;*************************************************************************************ENABLE BSF PORTB,6 ;Set ENABLE pin high CALL DELAY ;Minimum setup time for the LCD BCF PORTB,6 ;Falling edge needed to trigger LCD CALL DELAY ;Kill some time RETURN ;
DELAY MOVLW 0xFF ;Load 255 into W-register MOVWF MYREG ;Move this data into MYREGLOOP DECFSZ MYREG,1 ;Decrement MYREG, ans into MYREG GOTO LOOP ;Loop program till MYREG = 0 RETURN ;
LONGDELAY MOVLW 0XFF ; MOVWF DELAY2 ;LOOP2 DECFSZ DELAY2,1 ; GOTO LDELAY ; RETURN ;LDELAY MOVLW 0XFF ; MOVWF DELAY3 ;LOOP3 DECFSZ DELAY3,1 ; GOTO LOOP3 ; GOTO LOOP2 ;
DELAY1 MOVLW 0x60 ;Load 96 into W-register MOVWF MYREG2 ;Move this data into MYREGLOOP1 DECFSZ MYREG2,1 ;Decrement MYREG, ans into MYREG GOTO LOOP1 ;Loop program till MYREG = 0 RETURN
CLOCK BCF PORTB,4 ;Ensure that *Clock starts at 0 BSF PORTB,4 ;Clock value HIGH CALL DELAY ;Kill some time BCF PORTB,4 ;Falling edge *Clock CALL DELAY ;Kill some time RETURN ;
SERIAL MOVWF OUTPUT ;Moved data from W to OUTPUT regSERIAL1 BCF PORTB,5 ;Ensure that SERIAL pin starts @ 0 MOVLW 0x04 ;There are 4 bits to a nibble MOVWF MYREG1 ;Nibble control for escapeTEST BTFSC OUTPUT,7 ;Test data bit 7 BSF PORTB,5 ;SET SERIAL pin to 1 CALL CLOCK ;Clock the data to shift register BCF PORTB,5 ;Reset SERIAL pin for next test RLF OUTPUT,1 ;Rotate the OUTPUT register left DECFSZ MYREG1,1 ;Decrement MYREG1, ans into MYREG1 GOTO TEST ;Do next bit of the word till all done CALL ENABLE ;Enable the LCD to read the data RETURN ;Escape after the word is output
EX1 MOVF CODEDATA,0 ;Move data to w_reg
MOVWF NUMBER1 ;Move to number1 reg RETURN ;EX2 MOVF CODEDATA,0 ;Move data to w_reg MOVWF NUMBER2 ;Move to number2 reg RETURN ;EX3 MOVF CODEDATA,0 ;Move data to w_reg MOVWF NUMBER3 ;Move to number3 reg RETURN ;EX4 MOVF CODEDATA,0 ;Move data to w_reg MOVWF NUMBER4 ;Move to number4 reg RETURN ;EX5 MOVF CODEDATA,0 ;Move data to w_reg MOVWF NUMBER5 ;Move to number5 reg RETURN ;EX6 MOVF CODEDATA,0 ;Move data to w_reg MOVWF NUMBER6 ;Move to number6 reg GOTO CHECK ;
;*************************************************************************************; LCD Initialise *;*************************************************************************************START MOVLW 0x20 ;4 bit CALL SERIAL ;Move this data to the shift register MOVLW 0x28 ;4 bit, 2 line, 7x5 matrix CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 0x0C ;Disp ON, no cursor CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 0x02 ;Display & curser home CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 0x01 ;Clear display CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 0XC0 ;Address 40 CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot;
;*************************************************************************************; INTRO *;************************************************************************************* MOVLW 0X03 ;This is for three tries MOVWF COUNTER1 ;Counter for amount of attemptsZERO BSF PORTB,7 ;Character mode MOVLW 'D' ;D CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'i' ;i CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 's' ;s CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW '-' ;- CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'a' ;a CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'r' ;r CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'm' ;m CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'i' ;i CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'n' ;n CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'g' ;g CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot
MOVLW ' ' ; CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'C' ;C CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'o' ;o CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'd' ;d CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'e' ;e CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW '?' ;? CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot BCF PORTB,7 ;Command mode MOVLW 0X85 ;Address CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot
;*************************************************************************************; MAIN *;*************************************************************************************
CLEARS MOVLW 0X06 ;Setup maximum digits used MOVWF DIGITS ;This is the max digit used regTESTDATA MOVF DIGITS,0 ;Re-input number of digits left into W MOVWF DIGITS ;After movf, leave a copy again in DIGITS XORLW 0X06 ;Has a digit been input ? BTFSC STATUS,Z ;Well, has it CLRF CODEDATA ;Ensure that reg CODEDATA is empty
MOVF DIGITS,0 ;Re-input number of digits left into W MOVWF DIGITS ;Re-input number of digits left into W XORLW 0X05 ;2nd digit to follow ? BTFSC STATUS,Z ;Well, is it ? CALL EX1 ;Put the numeric value into the correct ;NUMBER register MOVF DIGITS,0 ;Re-input number of digits left into W MOVWF DIGITS ;Re-input number of digits left into W XORLW 0X04 ;3rd digit to follow ? BTFSC STATUS,Z ;Well, is it ? CALL EX2 ;Put the numeric value into the correct ;NUMBER register MOVF DIGITS,0 ;Re-input number of digits left into W MOVWF DIGITS ;Re-input number of digits left into W XORLW 0X03 ;4th digit to follow ? BTFSC STATUS,Z ;Well, is it ? CALL EX3 ;Put the numeric value into the correct ;NUMBER register MOVF DIGITS,0 ;Re-input number of digits left into W MOVWF DIGITS ;Re-input number of digits left into W XORLW 0X02 ;5th digit to follow ? BTFSC STATUS,Z ;Well, is it ? CALL EX4 ;Put the numeric value into the correct ;NUMBER register MOVF DIGITS,0 ;Re-input number of digits left into W MOVWF DIGITS ;Re-input number of digits left into W XORLW 0X01 ;6th digit to follow ? BTFSC STATUS,Z ;Well, is it ? CALL EX5 ;Put the numeric value into the correct ;NUMBER register MOVF DIGITS,0 ;Re-input number of digits left into W MOVWF DIGITS ;Re-input number of digits left into W XORLW 0X00 ;All six digits in ? BTFSC STATUS,Z ;Well, is it ? GOTO EX6 ;Put the numeric value into the correct ;NUMBER register BSF PORTA,0 ;Poke column 1 high
CALL DETERMINE ;Check PORTB lower nibble for change BCF PORTA,0 ;Clear column 1 BSF PORTA,1 ;Poke column 2 high CALL DETERMINE ;Check PORTB lower nibble for change BCF PORTA,1 ;Clear column 2 BSF PORTA,2 ;Poke column 3 high CALL DETERMINE ;Check PORTB lower nibble for change BCF PORTA,2 ;Clear column 3 GOTO TESTDATA ;Loop, check everything again
;*************************************************************************************; CALCULATION *;*************************************************************************************
CHECK MOVF NUMBER1,0 ;Put numeric input 1 into W register XORLW 0X05 ;Is the first saved value 5? BTFSS STATUS,Z ;Well, is it ? GOTO LOCKED ;No? start from scratch MOVF NUMBER2,0 ;Put numeric input 2 into W register XORLW 0X09 ;Is the second saved value 9? BTFSS STATUS,Z ;Well, is it ? GOTO LOCKED ;No? start from scratch MOVF NUMBER3,0 ;Put numeric input 3 into W register XORLW 0X07 ;Is the third saved value 7? BTFSS STATUS,Z ;Well, is it ? GOTO LOCKED ;No? start from scratch MOVF NUMBER4,0 ;Put numeric input 4 into W register XORLW 0X05 ;Is the fourth saved value 5? BTFSS STATUS,Z ;Well, is it ? GOTO LOCKED ;No? start from scratch MOVF NUMBER5,0 ;Put numeric input 5 into W register XORLW 0X03 ;Is the fifth saved value 3? BTFSS STATUS,Z ;Well, is it ? GOTO LOCKED ;No? start from scratch
MOVF NUMBER6,0 ;Put numeric input 6 into W register XORLW 0X01 ;Is the sixth saved value 1? BTFSS STATUS,Z ;Well, is it ? GOTO LOCKED ;No? start from scratch GOTO TWO ;Good the code is correct
;*************************************************************************************; DETERMINATION *;*************************************************************************************
DETERMINE BTFSC PORTB,0 ;Check first row GOTO DEBOUNCE ;Run debounce subroutine BTFSC PORTB,1 ;Check second row GOTO DEBOUNCE1 ;Run debounce routine BTFSC PORTB,2 ;Check third row GOTO DEBOUNCE2 ;Run debounce routine BTFSC PORTB,3 ;Check fouth row GOTO DEBOUNCE3 ;Run debounce routine RETURN ;
DEBOUNCE MOVLW 0X04 ;The amount of samples MOVWF COUNTER ;The sample registerTESTING CALL DELAY1 ;Kill some time BTFSS PORTB,0 ;Re-check this bit GOTO START ;False trigger, escape to start DECFSZ COUNTER,1 ;Re-sample 4 times GOTO TESTING ;DittoTEST1 BTFSC PORTB,0 ;Wait for release GOTO TEST1 ;Ditto BSF PORTB,7 ;R/S set to 1 for character display BTFSC PORTA,0 ;Was it the first column? GOTO i1 ;This is the character (without i ) BTFSC PORTA,1 ;Was it the second column? GOTO i2 ;This is the character (without i ) BTFSC PORTA,2 ;Was it the third column? GOTO i3 ;This is the character (without i )
GOTO START ;i1 MOVLW '*' ;* CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 0X01 ;Numeric value 1 MOVWF CODEDATA ;Save data for manipulation DECF DIGITS,1 ;Reduce digits register BCF PORTB,7 ;Command mode GOTO TESTDATA ;Redo the keypad scanningi2 MOVLW '*' ;* CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 0X02 ;Numeric value 2 MOVWF CODEDATA ;Save data for manipulation DECF DIGITS,1 ;Reduce digits register BCF PORTB,7 ;Command mode GOTO TESTDATA ;Redo the keypad scanningi3 MOVLW '*' ;* CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 0X03 ;Numeric value 3 MOVWF CODEDATA ;Save data for manipulation DECF DIGITS,1 ;Reduce digits register BCF PORTB,7 ;Command mode GOTO TESTDATA ;Redo the keypad scanningDEBOUNCE1 MOVLW 0X04 ;The amount of samples MOVWF COUNTER ;The sample registerTESTING1 CALL DELAY1 ;Kill some time BTFSS PORTB,1 ;Re-check this bit GOTO START ;False trigger, escape to start DECFSZ COUNTER,1 ;Re-sample 4 times GOTO TESTING1 ;DittoTEST2 BTFSC PORTB,1 ;Wait for release GOTO TEST2 ;Ditto BSF PORTB,7 ;R/S set to 1 for character display BTFSC PORTA,0 ;Was it the first column? GOTO i4 ;This is the character (without i ) BTFSC PORTA,1 ;Was it the second column? GOTO i5 ;This is the character (without i )
BTFSC PORTA,2 ;Was it the third column? GOTO i6 ;This is the character (without i ) GOTO START ;i4 MOVLW '*' ;* CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 0X04 ;Numeric value 4 MOVWF CODEDATA ;Save data for manipulation DECF DIGITS,1 ;Reduce digits register BCF PORTB,7 ;Command mode GOTO TESTDATA ;Redo the keypad scanningi5 MOVLW '*' ;* CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 0X05 ;Numeric value 5 MOVWF CODEDATA ;Save data for manipulation DECF DIGITS,1 ;Reduce digits register BCF PORTB,7 ;Command mode GOTO TESTDATA ;Redo the keypad scanningi6 MOVLW '*' ;* CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 0X06 ;Numeric value 6 MOVWF CODEDATA ;Save data for manipulation DECF DIGITS,1 ;Reduce digits register BCF PORTB,7 ;Command mode GOTO TESTDATA ;Redo the keypad scanningDEBOUNCE2 MOVLW 0X04 ;The amount of samples MOVWF COUNTER ;The sample registerTESTING2 CALL DELAY1 ;Kill some time BTFSS PORTB,2 ;Re-check this bit GOTO START ;False trigger, escape to start DECFSZ COUNTER,1 ;Re-sample 4 times GOTO TESTING2 ;DittoTEST3 BTFSC PORTB,2 ;Wait for release GOTO TEST3 ;Ditto BSF PORTB,7 ;R/S set to 1 for character display BTFSC PORTA,0 ;Was it the first column? GOTO i7 ;This is the character (without i )
BTFSC PORTA,1 ;Was it the second column? GOTO i8 ;This is the character (without i ) BTFSC PORTA,2 ;Was it the third column? GOTO i9 ;This is the character (without i ) GOTO START ;i7 MOVLW '*' ;* CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 0X07 ;Numeric value 7 MOVWF CODEDATA ;Save data for manipulation DECF DIGITS,1 ;Reduce digits register BCF PORTB,7 ;Command mode GOTO TESTDATA ;Redo the keypad scanningi8 MOVLW '*' ;* CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 0X08 ;Numeric value 8 MOVWF CODEDATA ;Save data for manipulation DECF DIGITS,1 ;Reduce digits register BCF PORTB,7 ;Command mode GOTO TESTDATA ;Redo the keypad scanningi9 MOVLW '*' ;* CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 0X09 ;Numeric value 9 MOVWF CODEDATA ;Save data for manipulation DECF DIGITS,1 ;Reduce digits register BCF PORTB,7 ;Command mode GOTO TESTDATA ;Redo the keypad scanningDEBOUNCE3 MOVLW 0X04 ;The amount of samples MOVWF COUNTER ;The sample registerTESTING3 CALL DELAY1 ;Kill some time BTFSS PORTB,3 ;Re-check this bit GOTO START ;False trigger, escape to start DECFSZ COUNTER,1 ;Re-sample 4 times GOTO TESTING3 ;DittoTEST4 BTFSC PORTB,3 ;Wait for release GOTO TEST4 ;Ditto BSF PORTB,7 ;R/S set to 1 for character display
BTFSC PORTA,0 ;Was it the first column? GOTO ix ;This is the character (without i ) BTFSC PORTA,1 ;Was it the second column? GOTO i0 ;This is the character (without i ) BTFSC PORTA,2 ;Was it the third column? GOTO i# ;This is the character (without i ) GOTO START ;Wasn't triggered,check againix MOVLW '*' ;* CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 0X2A ;ASCII symbol * MOVWF CODEDATA ;Save data for manipulation DECF DIGITS,1 ;Reduce digits register BCF PORTB,7 ;Command mode GOTO TESTDATA ;Redo the keypad scanningi0 MOVLW '*' ;* CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 0X00 ;Numeric value 0 MOVWF CODEDATA ;Save data for manipulation DECF DIGITS,1 ;Reduce digits register BCF PORTB,7 ;Command mode GOTO TESTDATA ;Redo the keypad scanningi# MOVLW '*' ;* CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 0X23 ;ASCII symbol # MOVWF CODEDATA ;Save data for manipulation DECF DIGITS,1 ;Reduce digits register BCF PORTB,7 ;Command mode GOTO TESTDATA ;Redo the keypad scanning
;*************************************************************************************; OUTCOMES *
;*************************************************************************************
LOCKED BCF PORTB,7 ;Command mode BSF PORTA,4 ;Red LED on MOVLW 0X01 ;Clear display CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 0X06 ;Increment display shift off CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 0X86 ;Address 6 CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot BSF PORTB,7 ;Character mode MOVLW 'W' ;W CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'R' ;R CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'O' ;O CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'N' ;N CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'G' ;G CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot BCF PORTB,7 ;Command mode MOVLW 0XC6 ;Address 45 CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot BSF PORTB,7 ;Character mode MOVLW 'C' ;C CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'O' ;O
CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'D' ;D CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'E' ;E CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot BCF PORTB,7 ;Command mode MOVLW 0X0A ;Flash 10 times MOVWF FLASH1 ;Flashing counterFLASH MOVLW 0X08 ;Display off CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot CALL LONGDELAY ;Kill a long time MOVLW 0X0C ;Display on CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot CALL LONGDELAY ;Kill a long time DECFSZ FLASH1,1 ;Reduce amount of flashes by 1 GOTO FLASH ;Make the display flash on and off BCF PORTB,7 ;Command mode MOVLW 0X01 ;Clear display CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 0XC0 ;Address 40 CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot BCF PORTA,4 ;Red LED off DECFSZ COUNTER1,1 ;Count if max attempt reached GOTO ZERO ;Re-ask for the codeONE BSF PORTA,4 ;Red LED on BCF PORTB,7 ;Command mode MOVLW 0X01 ;Clear display CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 0X85 ;Address 05 CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot BSF PORTB,7 ;Character mode
MOVLW 'L' ;L CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'O' ;O CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'C' ;C CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'K' ;K CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'E' ;E CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'D' ;D CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot BCF PORTB,7 ;Command mode MOVLW 0XC0 ;Address 40 CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot BSF PORTB,7 ;Character mode MOVLW 'U' ;U CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 's' ;s CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'e' ;e CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW ' ' ; CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'M' ;M CALL SERIAL ;This will output 4 bits only
CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'a' ;a CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 's' ;s CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 't' ;t CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'e' ;e CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'r' ;r CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW ' ' ; CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'C' ;C CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'o' ;o CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'd' ;d CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'e' ;e CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot GOTO $ ;TWO BCF PORTB,7 ;Command mode MOVLW 0X01 ;Clear display CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 0X82 ;Address 02
CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot BSF PORTA,3 ;Green LED on BSF PORTB,7 ;Character mode MOVLW 'D' ;D CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'e' ;e CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW '-' ;- CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'A' ;a CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'c' ;c CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 't' ;t CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'i' ;i CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'v' ;v CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'a' ;a CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 't' ;t CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot MOVLW 'e' ;e CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot
MOVLW 'd' ;d CALL SERIAL ;This will output 4 bits only CALL SERIAL1 ;cause the low 4 are already high rot;************************************************************************************* GOTO $ ; END
microchip 16F877 tlcd
;
Title "LCD test."
;
list P = 16F877
;
include "P16f877.inc"
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _HS_OSC & _WRT_ENABLE_ON & _LVP_ON & _DEBUG_OFF & _CPD_OFF
;
; --------------------
; USER RAM DEFINITIONS
; --------------------
;
CBLOCK 0x20
;
MessPt
DisData
DelayL
DelayM
DelayH
Temp
;
ENDC
lcdRW equ 2h ; RB2 = LCD RW pin
lcdRS equ 4h ; RB4 = LCD RS pin
lcdE equ 5h ; RB5 = LCD E pin
; PORTD USED FOR LCD DATA PINS RB0 - RB7 = D0 - D7
;
; ---------------------
; YOUR CODE BEGINS HERE
; ---------------------
;
org 0x0000
clrf PORTA
clrf PORTD
clrf PORTC
clrf PORTD
clrf PORTE
bsf STATUS,RP0 ; RAM Page 1
clrf TRISA
clrf TRISB
clrf TRISC
clrf TRISD
clrf TRISE
;
; -------------------------
; SET ANALOG/DIGITAL INPUTS
; -------------------------
;
movlw b'00000110' ; = all digital
movwf ADCON1
bcf STATUS,RP0
movlw 20h ; 25mS powerup delay @ 4MHz
movwf DelayH ; data sheet says 15mS
clrf DelayL
PUPD decfsz DelayL
goto PUPD
decfsz DelayH
goto PUPD
call Control ; initialize display
;
; -----------------------------------------------------
; DISPLAY THE MESSAGE WHEN THE BUTTON ON RA3 IS PRESSED
; -----------------------------------------------------
;
MnLoop clrf MessPt
movlw 0x80 ; line 1
call LCDins
Loop1 call TheText
xorlw 0h
btfsc STATUS,Z
goto DoLine2
call LCDout
incf MessPt
goto Loop1
DoLine2 incf MessPt
movlw 0xC0 ; line 2
call LCDins
Loop2 call TheText
xorlw 0h
btfsc STATUS,Z
goto DoDelay
call LCDout
incf MessPt
goto Loop2
DoDelay call BigDel ; wait
goto MnLoop
;
; ------------------------
; LCD INITIALIZATION CODES
; ------------------------
;
TheText movlw High($)
movwf PCLATH
movf MessPt,W
addwf PCL
DT " HELLO FROM", 0h
DT " THE PIC 16F873", 0h
;
; -----------------
; SEND CONTROL DATA
; -----------------
; According to the data sheet, a delay of 4mS minimum must occur
; between each control data byte being sent.
;
Control movlw 38h ; (128) display initialisation
call LCDins ; output to display
movlw 38h ; page 45 of the data sheet
call LCDins ; output to display
movlw 38h ; two line
call LCDins ; output to display
movlw .6 ; increment display
call LCDins ; output to display
movlw 0ch ; display = on, cursor = off
call LCDins ; output to display
movlw .1 ; clear display
call LCDins ; output to display
return
;
; -----------------------------
; OUTPUT 1 DATA BYTE TO DISPLAY
; -----------------------------
;
LCDout movf DisData,w
movwf PORTD
bsf PORTB,lcdRS ; (4) Write data to display
call Clock
bsf PORTB,lcdE ; (5) enable
call Clock
bcf PORTB,lcdE ; (5)
call Clock
bcf PORTB,lcdRS ; (5)
bcf STATUS,RP0 ; ram page 0
return
;
; ------------------------------------
; OUTPUT 1 INSTRUCTION BYTE TO DISPLAY
; ------------------------------------
;
LCDins movf DisData,w
movwf PORTD
bcf PORTB,lcdRS ; (4) Write instruction to display
call Clock
bsf PORTB,lcdE ; (5) enable
call Clock
bcf PORTB,lcdE ; (5)
call Clock
clrf DelayL
movlw 8h ; about 6mS delay @ 4MHz
movwf DelayH
ctlp1 decfsz DelayL
goto ctlp1
decfsz DelayH
goto ctlp1
return
;
; -----------------------------
; CLOCKING DELAY - 200uS @ 4MHz
; -----------------------------
;
Clock movlw 40h
movwf DelayL
kdloop decfsz DelayL
goto kdloop
return
;
; --------------------------------
; ABOUT A HALF SECOND DELAY @ 4MHz
; --------------------------------
;
BigDel clrf DelayL
clrf DelayM
movlw 5h
movwf DelayH
BDloop decfsz DelayL
goto BDloop
decfsz DelayM
goto BDloop
decfsz DelayH
goto BDloop
return
test movlw 8h
movwf DelayH
ctlp2 decfsz DelayL
goto ctlp2
decfsz DelayH
goto ctlp2
return
;
; -----------------------
; BOOT CODE START ADDRESS
; -----------------------
; DO NOT PLACE ANY CODE PAST THIS POINT
;
org 0x0F00
;
;
end
PIC 4 bit 16x2 Hitachi 44780 LCD driver
by Anonymous
NEW!
LCD Front Panel:2x16, HD44780, 4buttons, 3LEDs $8.95 7 in stock
Here's a driver for a standard 16 char by 2 line LCD that I wrote.
The driver sets the LCD up for 4 bit mode, and is write only. Hence only 6 I/O pins are used. Data lines 4-7 go to pins A0-A4, and the Register Select and Enable lines can be chosen by the user as long as they are on port B by saying something like
LCDEnable equ 3 ; The LCD enable pin on Port B
LCDRS equ 4; The LCD R/S pins on Port B
NOTE: This code presently uses a 14.7456 mhz crystal. To use a differeny xtal, use the PIClist delay code generator to change the values of the delays. The delay times are not that critical.
To use this code, firstly set the relevent TRIS bits, then initialise the LCD:
CALL LONGDLY
CALL LCDFUN ; sets the LCD's function to 4 bit, 2 line, 5x7 font
CALL LONGDLY
CALL LCDDISP ; Turns on the display and cursor
CALL LONGDLY
CALL LCDENT ; sets auto increment right after write (like a typewriter)
CALL LCDCLR
You know the LCD is initialized when iot is totally blank. If you get the one row solid black and the other clear, the LCD has not been initialised properly.
Now, there are 2 ways to write to the LCD. Firstly, you can use the LCDChar method. This is nice because it automatcally word wraps the text, and prevents you writing to non- visible memory. For instance:
movlw "A"
movwf LCDByte
CALL LCDCHAR
To write different commands to the LCD, such as different function select bytes, set the relevent RS bit, put the data in LCDByte, then call LCDBYTE. This is only for the LCD gurus!
To change the address, call LCDADD eg to go to address 3,
movlw 3
movwf LCDadd
CALL LCDADD
To clear the LCD,
CALL LCDCLR.
To 'backspace',
CALL LCDBACKSPACE
LCDADD ; makes LCDAdd the current LCD Address
nop
BCF PORTB,LCDRS
movf LCDAdd, 0
movwf LCDByte
bsf LCDByte, 7
CALL LCDBYTE
bsf PORTB,LCDRS
nop
nop
RETURN
LCDENT ; Entry Mode set - currently set to move cursor to right after each write
nop
BCF PORTB, LCDRS
movlw b'00000110'
movwf LCDByte
CALL LCDBYTE
BSF PORTB,LCDRS
nop
nop
RETURN
LCDDISP ; turns on display and cursor
nop
BCF PORTB,LCDRS
movlw b'00001110'
movwf LCDByte
CALL LCDBYTE
BSF PORTB,LCDRS
nop
nop
RETURN
LCDFUN ; sets up the LCD function byte, for 4 bit control, 2 lines, standard font
nop
movlw d'2'
movwf nibToSend
BCF PORTB, LCDRS ; we're sending a command, so R/S must be lo
CALL SENDNIB ; due to 4 bit operation, we have to resend the first nibble
CALL SHORTDLY
movlw b'00101000'
movwf LCDByte
CALL LCDBYTE
BSF PORTB, LCDRS
nop
nop
RETURN
LCDCLR ; clears the entire display
clrf LCDAdd
nop
movlw d'1'
movwf LCDByte
BCF PORTB, LCDRS ; 'cause we are doing a command, set the R/S line lo
CALL LCDBYTE ; writes LCDByte to the LCD
CALL LONGDLY ; Clearing the LCD takes ages, so a larger delay is needed
bsf PORTB, LCDRS ; set the R/S line, ready for characters
RETURN
LCDCHAR
;use this for displaying characters only, NOT control chars
;keeps track of cursor colation, and word wraps if necessary
movf LCDAdd, 0
sublw h'50'
btfsc STATUS, Z
RETURN
CALL LCDBYTE
incf LCDAdd, 1
; check if we have hit the end of the top line
movlw d'16'
subwf LCDAdd, 0
btfsc STATUS, Z ; skip if not zero
GOTO LCDLINE2 ; must go to new line
RETURN
LCDLINE2
; here we must go to the new line
movlw b'01000000'
movwf LCDAdd
CALL LCDADD
RETURN
LCDBYTE; sends a byte to the LCD, in 4bit fashion
; responsible for breaking up the byte to send into high and low nibbles
; and dumps them to LCD
;NOT responsible for the status of the LCDRS line, nor the major delays
; IN: LCDByte - distructive OUT: hiByte, loByte
clrf hiByte ; clears the vars, to prevent bugs
clrf loByte
bcf STATUS,0 ; get rif of any carry which could screw up the bitshifts
rlf LCDByte, 1
rlf hiByte
rlf LCDByte, 1
rlf hiByte
rlf LCDByte, 1
rlf hiByte
rlf LCDByte, 1
rlf hiByte
movf LCDByte, 0
movwf loByte
swapf loByte, 1
movf hiByte,0
movwf nibToSend
CALL SENDNIB
movf loByte,0
movwf nibToSend
CALL SENDNIB
CALL SHORTDLY ; blocks until most instructions are done
RETURN
SENDNIB; responsible for sending nibble commands to the LCD.
;IN: nibToSend - non-distructive
clrf W ; clears W
movf nibToSend, 0
movwf PORTA
nop
bsf PORTB, LCDEnable; pulse the LCD Enable high
nop
nop
bcf PORTB, LCDEnable ; lower LCD Enable
nop
nop
RETURN
SHORTDLY ; around 50us
;217 cycles
movlw 0x48
movwf d1
SHORTDLY_0
decfsz d1, f
goto SHORTDLY_0
;4 cycles (including call)
return
LONGDLY ; 25ms delay
;92153 cycles
movlw 0xFE
movwf d1
movlw 0x48
movwf d2
LONGDLY_0
decfsz d1, f
goto $+2
decfsz d2, f
goto LONGDLY_0
;3 cycles
goto $+1
nop
;4 cycles (including call)
return
LCDBACKSPACE ; acts like a backspace
movf LCDAdd,0
andlw b'11111111'
btfsc STATUS, Z ; skip if not zero
RETURN ; already at end, so ignore backspace
sublw h'40'
btfsc STATUS, Z ; skip if at start of 2nd line
GOTO LCDBSTARTBOTLINE ; correct for moveing up to new line
decf LCDAdd, 1;
CALL LCDADD ; move back one
movlw d'32' ; wipe the current char
movwf LCDByte
CALL LCDBYTE
CALL LCDADD
RETURN
LCDBSTARTBOTLINE ; correct for moveing up to new line
movlw d'15'
movwf LCDAdd
CALL LCDADD ; put us at 15
movlw d'32'
movwf LCDByte
CALL LCDBYTE
RETURN
;----------------------------------------------------------------------;; WKTIM4M.ASM Pushbutton toggles clock on and off, time on LCD 4 MHz ; ;----------------------------------------------------------------------;
; Note: must add additional time digit to run over 99 hrs.
; .-----------.; -|RA2 RA1|----[LCD E] ; -|RA3 RA0|----[LCD RS] ; -|RA4 OSC1|--|X|-||--- gnd ; V+ ---|MCLR OSC2|--|X|-||--- gnd ; gnd ---|Vss Vdd|--- V+ ; [LCD D4]----|RB0 RB7|- X = 4.096 MHz xtal 20 pfd; [LCD D5]----|RB1 RB6|- V+ = 4.5 or 5 Volts; [LCD D6]----|RB2 RB5|- ; [LCD D7]----|RB3 RB4|---[PB]--- gnd ; '-----------' ; PIC16F84 -[PB]- pushbutton
; LCD pin connections:; 1 - gnd ground 2 - Vcc V+ 3 - contrast 10K pot V+ & gnd; 4 - RS RA0 PIC(17) 5 - RW gnd 6 - E RA1 PIC(18) ; 7 - D0 gnd 8 - D1 gnd 9 - D2 gnd 10 - D3 gnd ; 11 - D4 RB0 (6) 12 - D5 RB1 (7) 13 - D6 RB2 (8) 14 - D7 (9)
LIST P=16F84 ; 16F84 Runs at 4.096 MHz INCLUDE "p16f84.inc" __CONFIG _PWRTE_ON & _XT_OSC & _WDT_OFF ERRORLEVEL -224 ; supress annoying message from tris
; Define Information #DEFINE RS PORTA, 0 #DEFINE E PORTA, 1 #DEFINE TOGGLESW PORTA, 4
; Macro
EStrobe MACRO ; Strobe the "E" Bit bsf E bcf E ENDM
CBLOCK 0CH sec ; seconds digit sec10 ; 10's of second digit mins ; minutes digit min10 ; 10's of minutes digit hr ; hours digit hr10 ; 10's of hours digit highlim ; high limit + 1 of digit w_temp ; holds W during interrupt
status_temp ; holds STATUS during interrupt fsr_temp ; holds FSR during interrupt Dlay ; 8 Bit Delay Variable working ; working flag 0 not working, 1 working ptr ; used in displaying message Temp ; a temporary variable bin ; a temporary variable oset ; offset of time register oldtime ; holds last value of sec cntmsec ; used in counting milliseconds isrcnt ; used in isr to stretch time to 1 sec ENDC ORG 0 ; start at location 0
goto main ; jump over to main routine
ORG 4 goto isr ; jump to interrupt routine
;----------------------------------------------------------------------;; High limit + 1 of digits at position W ;;----------------------------------------------------------------------;sethi: addwf PCL, f dt H'A',H'6',H'A',H'6',H'A',H'A'
;----------------------------------------------------------------------;; Data for message to be output ;;----------------------------------------------------------------------;shomsg ; Message to Output addwf PCL, f ; Output the Characters dt "Working Time:", 0
;----------------------------------------------------------------------;; ISR, increments time by one second, (BCD), every 125th time through ;;----------------------------------------------------------------------;isr: movwf w_temp ; save W swapf STATUS,W ; save status movwf status_temp ; without changing flags swapf FSR,W ; save FSR movwf fsr_temp ; without changing flags
decfsz isrcnt, f ; count down to zero before incr. goto restore movlw D'125' ; reset isr count movwf isrcnt movf working, f ; check working flag btfsc STATUS, Z ; if not zero then increment time
goto restore ; else get out of interrupt routine
movlw sec ; point at sec register movwf FSRnewdigit: incf INDF, f ; current digit up one movlw sec ; get difference, sec and FSR subwf FSR, W call sethi ; use to get high limit + 1 subwf INDF, W ; reached that number yet? btfss STATUS, Z ; skip over if yes goto restore ; else exit isr clrf INDF ; set current digit to 0 incf FSR, f ; point at next digit goto newdigit ; no, increment the next digitrestore: swapf status_temp,W ; get original status back movwf STATUS ; into status register swapf fsr_temp,W ; get original fsr back movwf FSR ; into status register swapf w_temp,f ; old no flags trick again swapf w_temp,W ; to restore W bcf INTCON,T0IF ; clear the TMR0 interrupt flag retfie ; finished reset GIE
;----------------------------------------------------------------------;; Initialize the ports ;;----------------------------------------------------------------------;init: clrf PORTA clrf PORTB
movlw B'00010000' ; RA4 input, others outputs tris PORTA movlw B'00000000' ; all outputs on port B tris PORTB movlw B'00000011' ; pull-ups enabled ; prescaler assigned to TMR0 ; prescaler set to 1:16 ; rolls over each 125th second option movlw 0 ; zero out all registers movwf hr10 movwf hr movwf min10 movwf mins movwf sec10 movwf sec clrf working ; working flag to zero
movlw B'10100000' ; GIE set T0IE set, T0IF cleared movwf INTCON return
;----------------------------------------------------------------------;
; Initialize the LCD ;;----------------------------------------------------------------------;initlcd: movlw D'40' call nmsec ; Wait 40 msecs before Reset bcf RS ; send an 8 bit instruction movlw 0x03 ; Reset Command call NybbleOut ; Send the Nybble call Dlay5 ; Wait 5 msecs before Sending Again EStrobe call Dlay160 ; Wait 160 usecs before Sending 2nd Time EStrobe call Dlay160 ; Wait 160 usecs before Sending 3rd Time bcf RS ; send an 8 bit instruction movlw 0x02 ; Set 4 Bit Mode call NybbleOut call Dlay160 movlw 0x028 ; 4 bit, 2 Line, 5x7 font call SendINS movlw 0x010 ; display shift off call SendINS movlw 0x001 ; Clear the Display RAM call SendINS call Dlay5 ; Note, Can take up to 4.1 msecs movlw 0x006 ; increment cursor call SendINS movlw 0x00C ; display on cursor off call SendINS return
;----------------------------------------------------------------------;; Send the character in W out to the LCD ;;----------------------------------------------------------------------;SendASCII addlw '0' ; Send nbr as ASCII characterSendCHAR ; Send the Character to the LCD movwf Temp ; Save the Temporary Value swapf Temp, w ; Send the High Nybble bsf RS ; RS = 1 call NybbleOut movf Temp, w ; Send the Low Nybble bsf RS call NybbleOut return
;----------------------------------------------------------------------;; Send an instruction in W out to the LCD ;;----------------------------------------------------------------------;SendINS ; Send the Instruction to the LCD movwf Temp ; Save the Temporary Value swapf Temp, w ; Send the High Nybble
bcf RS ; RS = 0 call NybbleOut movf Temp, w ; Send the Low Nybble bcf RS call NybbleOut return
;----------------------------------------------------------------------;; Send the nibble in W out to the LCD ;;----------------------------------------------------------------------;NybbleOut ; Send a Nybble to the LCD movwf PORTB EStrobe ; Strobe out the LCD Data call Dlay160 ; delay for 160 usec return
;----------------------------------------------------------------------;; Output the message on the LCD ;;----------------------------------------------------------------------;OutMessage: movwf FSR ; Point at first letterOutLoop: movf FSR, w ; Get pointer into W incf FSR, f ; Set up for next letter call shomsg ; Get character to output iorlw 0 ; At the End of the Message? btfsc STATUS, Z ; Skip if not at end return ; Yes - Equal to Zero call SendCHAR ; Output the ASCII Character goto OutLoop ; Get the next character
;----------------------------------------------------------------------;; Wait until button is released ;;----------------------------------------------------------------------;waitup: btfss TOGGLESW ; test toggle switch goto $ -1 ; ck again if pressed movlw 20 ; wait 20 msec for debounce call nmsec btfss TOGGLESW ; check again, still up? goto $ -4 ; no start over return ; yes, finished
;----------------------------------------------------------------------;; time delay routines ;;----------------------------------------------------------------------;
Dlay160: movlw D'41' ; delay about 160 usec
micro4 addlw H'FF' ; subtract 1 from 'W' btfss STATUS,Z ; skip when you reach zero goto micro4 ; more loops return
Dlay5: movlw 5 ; delay for 5 milliseconds goto $ + 2msec250: movlw D'250' ; delay for 250 milliseconds ;*** N millisecond delay routine ***nmsec: movwf cntmsec ; delay for N (in W) millisecmsecloop: movlw D'254' ; load takes .9765625 microsec call micro4 ; by itself CALL takes ... ; 2 + 253 X 4 + 3 + 2 = 1019 ; 1019 * .977 = 995 microsec nop ; .98 microsec decfsz cntmsec, f ; .98 skip not taken, else 1.95 goto msecloop ; 1.95 here: total ~1000 / loop return ; final time through ~999 to here ; overhead in and out ignored
;----------------------------------------------------------------------;; Display the Time ;;----------------------------------------------------------------------;DispTime MOVLW H'C0' ; position at beginning of second line CALL SendINS MOVF hr10, W ; tens of hours CALL SendASCII MOVF hr, W ; hours CALL SendASCII MOVLW ":" CALL SendCHAR MOVF min10, W ; tens of minutes CALL SendASCII MOVF mins, W ; minutes CALL SendASCII MOVLW ":" CALL SendCHAR MOVF sec10, W ; tens of seconds CALL SendASCII MOVF sec, W ; seconds CALL SendASCII RETURN ;----------------------------------------------------------------------;; Toggle Work Flag ;;----------------------------------------------------------------------;togglewk: movf working, f ; set zero flag if zero btfss STATUS, Z ; skip if working is zero goto turnoff incf working, f ; set working to 1 call waitup ; wait for button release
returnturnoff: clrf working ; working set to zero call waitup ; wait for button to be released return
;----------------------------------------------------------------------;; The Main routine ;;----------------------------------------------------------------------;main: call init ; initialize ports, set up timer call initlcd ; initialize the LCD movlw 0 ; display 'Working Time:' call OutMessageckbutton: ; check for a press of the TOGGLE button btfss TOGGLESW ; skip if not pressed call togglewk ; else change the mode of timer movf oldtime, W ; is oldtime the same as sec? subwf sec, W btfsc STATUS, Z ; if not, skip over next instruction goto ckbutton ; else continue checking call DispTime ; sec has changed, display the time movf sec, W ; make sec and oldsec the same movwf oldtime goto ckbutton ; and continue checking
end