3x4 Keypad Lock w

49
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 pin MYREG1 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 ;

Transcript of 3x4 Keypad Lock w

Page 1: 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 ;

Page 2: 3x4 Keypad Lock w

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 ;

Page 3: 3x4 Keypad Lock w

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

Page 4: 3x4 Keypad Lock w

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;

Page 5: 3x4 Keypad Lock w

;*************************************************************************************; 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

Page 6: 3x4 Keypad Lock w

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

Page 7: 3x4 Keypad Lock w

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

Page 8: 3x4 Keypad Lock w

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

Page 9: 3x4 Keypad Lock w

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 )

Page 10: 3x4 Keypad Lock w

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 )

Page 11: 3x4 Keypad Lock w

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 )

Page 12: 3x4 Keypad Lock w

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

Page 13: 3x4 Keypad Lock w

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 *

Page 14: 3x4 Keypad Lock w

;*************************************************************************************

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

Page 15: 3x4 Keypad Lock w

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

Page 16: 3x4 Keypad Lock w

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

Page 17: 3x4 Keypad Lock w

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

Page 18: 3x4 Keypad Lock w

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

Page 19: 3x4 Keypad Lock w

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

Page 20: 3x4 Keypad Lock w

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

Page 21: 3x4 Keypad Lock w

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

; -----------------------------------------------------

;

Page 22: 3x4 Keypad Lock w

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

;

Page 23: 3x4 Keypad Lock w

; ------------------------

; 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

Page 24: 3x4 Keypad Lock w

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

Page 25: 3x4 Keypad Lock w

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

;

; --------------------------------

Page 26: 3x4 Keypad Lock w

; 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

;

Page 27: 3x4 Keypad Lock w

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:

Page 28: 3x4 Keypad Lock w

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

Page 29: 3x4 Keypad Lock w

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

Page 30: 3x4 Keypad Lock w

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

Page 31: 3x4 Keypad Lock w

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

Page 32: 3x4 Keypad Lock w

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

Page 33: 3x4 Keypad Lock w

; 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

Page 34: 3x4 Keypad Lock w

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

Page 35: 3x4 Keypad Lock w

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'

Page 36: 3x4 Keypad Lock w

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

Page 37: 3x4 Keypad Lock w

;----------------------------------------------------------------------;; 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

Page 38: 3x4 Keypad Lock w

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

Page 39: 3x4 Keypad Lock w

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

;----------------------------------------------------------------------;

Page 40: 3x4 Keypad Lock w

; 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

Page 41: 3x4 Keypad Lock w

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

Page 42: 3x4 Keypad Lock w

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

Page 43: 3x4 Keypad Lock w

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