You are on page 1of 43

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 ; CLRF NUMBER4 ; CLRF NUMBER5 ; CLRF NUMBER6 ; CLRF COUNTER ; CLRF OUTPUT ; CLRF MYREG ; CLRF MYREG1 ; CLRF MYREG2 ; CLRF DIGITS ; CLRF FLASH1 ;

CLRF BSF MOVLW MOVWF MOVLW inputs MOVWF BCF BCF command mode CLRF are at zero GOTO

COUNTER1 STATUS,5 0X00 TRISA 0X0F TRISB STATUS,5 PORTB,7 PORTA START

; ;Select bank 1 ;All outputs ;Ditto ;Lower nibble is ;Ditto ;Back to bank 0 ;R/S Set to zero;Ensure all outputs ;

;********************************************************************* **************** ; 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 register MYREG LOOP ans into MYREG MYREG = 0 RETURN ; MOVLW MOVWF DECFSZ GOTO 0xFF MYREG MYREG,1 LOOP ;Load 255 into W;Move this data into ;Decrement MYREG, ;Loop program till

LONGDELAY LOOP2 LDELAY LOOP3

MOVLW MOVWF DECFSZ GOTO RETURN MOVLW MOVWF DECFSZ GOTO GOTO MOVLW MOVWF

0XFF DELAY2 DELAY2,1 LDELAY 0XFF DELAY3 DELAY3,1 LOOP3 LOOP2 0x60 MYREG2 MYREG2,1 LOOP1

; ; ; ; ; ; ; ; ; ; ;Load 96 into W;Move this data into ;Decrement MYREG, ;Loop program till

DELAY1 register MYREG LOOP1 ans into MYREG MYREG = 0

DECFSZ GOTO RETURN

CLOCK starts at 0

BCF BSF CALL BCF CALL RETURN

PORTB,4 PORTB,4 DELAY PORTB,4 DELAY

;Ensure that *Clock ;Clock value HIGH ;Kill some time ;Falling edge *Clock ;Kill some time ; ;Moved data from W ;Ensure that SERIAL ;There are 4 bits to ;Nibble control for ;Test data bit 7 ;SET SERIAL pin to 1 ;Clock the data to ;Reset SERIAL pin ;Rotate the OUTPUT ;Decrement MYREG1, ;Do next bit of the ;Enable the LCD to ;Escape after the

SERIAL to OUTPUT reg SERIAL1 pin starts @ 0 a nibble

MOVWF BCF MOVLW MOVWF

OUTPUT PORTB,5 0x04 MYREG1 OUTPUT,7 PORTB,5 CLOCK PORTB,5 OUTPUT,1 MYREG1,1 TEST ENABLE

escape TEST shift register

BTFSC BSF CALL BCF

for next test RLF register left DECFSZ ans into MYREG1 GOTO word till all done CALL read the data RETURN word is output EX1 MOVF

CODEDATA,0

;Move data to w_reg

EX2 EX3 EX4 EX5 EX6

MOVWF RETURN MOVF MOVWF RETURN MOVF MOVWF RETURN MOVF MOVWF RETURN MOVF MOVWF RETURN MOVF MOVWF GOTO

NUMBER1 CODEDATA,0 NUMBER2 CODEDATA,0 NUMBER3 CODEDATA,0 NUMBER4 CODEDATA,0 NUMBER5 CODEDATA,0 NUMBER6 CHECK

;Move ; ;Move ;Move ; ;Move ;Move ; ;Move ;Move ; ;Move ;Move ; ;Move ;Move ;

to number1 reg data to w_reg to number2 reg data to w_reg to number3 reg data to w_reg to number4 reg data to w_reg to number5 reg data to w_reg to number6 reg

;********************************************************************* **************** ; 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 attempts ZERO 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 bits only CALL already high rot MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot BCF MOVLW CALL bits only CALL already high rot

' ' SERIAL SERIAL1 'C' SERIAL SERIAL1 'o' SERIAL SERIAL1 'd' SERIAL SERIAL1 'e' SERIAL SERIAL1 '?' SERIAL SERIAL1 PORTB,7 0X85 SERIAL SERIAL1

; ;This will output 4 ;cause the low 4 are ;C ;This will output 4 ;cause the low 4 are ;o ;This will output 4 ;cause the low 4 are ;d ;This will output 4 ;cause the low 4 are ;e ;This will output 4 ;cause the low 4 are ;? ;This will output 4 ;cause the low 4 are ;Command mode ;Address ;This will output 4 ;cause the low 4 are

;********************************************************************* **************** ; MAIN * ;********************************************************************* **************** CLEARS digits used MOVLW 0X06 DIGITS DIGITS,0 DIGITS 0X06 STATUS,Z CODEDATA ;Setup maximum ;This is the max ;Re-input number of ;After movf, leave a ;Has a digit been ;Well, has it ;Ensure that reg

MOVWF digit used reg TESTDATA MOVF digits left into W MOVWF copy again in DIGITS XORLW input ? BTFSC CLRF CODEDATA is empty

MOVF digits left into W MOVWF digits left into W XORLW ? BTFSC CALL value into the correct MOVF digits left into W MOVWF digits left into W XORLW ? BTFSC CALL value into the correct MOVF digits left into W MOVWF digits left into W XORLW ? BTFSC CALL value into the correct MOVF digits left into W MOVWF digits left into W XORLW ? BTFSC CALL value into the correct MOVF digits left into W MOVWF digits left into W XORLW ? BTFSC CALL value into the correct MOVF digits left into W MOVWF digits left into W XORLW BTFSC GOTO value into the correct BSF

DIGITS,0 DIGITS 0X05 STATUS,Z EX1 DIGITS,0 DIGITS 0X04 STATUS,Z EX2 DIGITS,0 DIGITS 0X03 STATUS,Z EX3 DIGITS,0 DIGITS 0X02 STATUS,Z EX4 DIGITS,0 DIGITS 0X01 STATUS,Z EX5 DIGITS,0 DIGITS 0X00 STATUS,Z EX6 PORTA,0

;Re-input number of ;Re-input number of ;2nd digit to follow ;Well, is it ? ;Put the numeric ;NUMBER register ;Re-input number of ;Re-input number of ;3rd digit to follow ;Well, is it ? ;Put the numeric ;NUMBER register ;Re-input number of ;Re-input number of ;4th digit to follow ;Well, is it ? ;Put the numeric ;NUMBER register ;Re-input number of ;Re-input number of ;5th digit to follow ;Well, is it ? ;Put the numeric ;NUMBER register ;Re-input number of ;Re-input number of ;6th digit to follow ;Well, is it ? ;Put the numeric ;NUMBER register ;Re-input number of ;Re-input number of ;All six digits in ? ;Well, is it ? ;Put the numeric ;NUMBER register ;Poke column 1 high

CALL nibble for change BCF BSF CALL nibble for change BCF BSF CALL nibble for change BCF GOTO everything again

DETERMINE PORTA,0 PORTA,1 DETERMINE PORTA,1 PORTA,2 DETERMINE PORTA,2 TESTDATA

;Check PORTB lower ;Clear column 1 ;Poke column 2 high ;Check PORTB lower ;Clear column 2 ;Poke column 3 high ;Check PORTB lower ;Clear column 3 ;Loop, check

;********************************************************************* **************** ; CALCULATION * ;********************************************************************* **************** CHECK MOVF into W register XORLW value 5? BTFSS GOTO scratch MOVF into W register XORLW value 9? BTFSS GOTO scratch MOVF into W register XORLW value 7? BTFSS GOTO scratch MOVF into W register XORLW value 5? BTFSS GOTO scratch MOVF into W register XORLW value 3? BTFSS GOTO scratch NUMBER1,0 0X05 STATUS,Z LOCKED NUMBER2,0 0X09 STATUS,Z LOCKED NUMBER3,0 0X07 STATUS,Z LOCKED NUMBER4,0 0X05 STATUS,Z LOCKED NUMBER5,0 0X03 STATUS,Z LOCKED ;Put numeric input 1 ;Is the first saved ;Well, is it ? ;No? start from ;Put numeric input 2 ;Is the second saved ;Well, is it ? ;No? start from ;Put numeric input 3 ;Is the third saved ;Well, is it ? ;No? start from ;Put numeric input 4 ;Is the fourth saved ;Well, is it ? ;No? start from ;Put numeric input 5 ;Is the fifth saved ;Well, is it ? ;No? start from

MOVF into W register XORLW value 1? BTFSS GOTO scratch GOTO correct

NUMBER6,0 0X01 STATUS,Z LOCKED TWO

;Put numeric input 6 ;Is the sixth saved ;Well, is it ? ;No? start from ;Good the code is

;********************************************************************* **************** ; DETERMINATION * ;********************************************************************* **************** DETERMINE subroutine BTFSC GOTO routine BTFSC GOTO routine BTFSC GOTO routine RETURN DEBOUNCE samples TESTING escape to start DECFSZ GOTO TEST1 BTFSC GOTO BSF character display BTFSC column? GOTO character (without i ) BTFSC column? GOTO character (without i ) BTFSC column? GOTO character (without i ) COUNTER,1 TESTING PORTB,0 TEST1 PORTB,7 PORTA,0 i1 PORTA,1 i2 PORTA,2 i3 ;Re-sample 4 times ;Ditto ;Wait for release ;Ditto ;R/S set to 1 for ;Was it the first ;This is the ;Was it the second ;This is the ;Was it the third ;This is the MOVLW MOVWF CALL BTFSS GOTO 0X04 COUNTER DELAY1 PORTB,0 START ; ;The amount of ;The sample register ;Kill some time ;Re-check this bit ;False trigger, PORTB,3 DEBOUNCE3 ;Check fouth row ;Run debounce PORTB,2 DEBOUNCE2 ;Check third row ;Run debounce PORTB,1 DEBOUNCE1 ;Check second row ;Run debounce BTFSC GOTO PORTB,0 DEBOUNCE ;Check first row ;Run debounce

i1 bits only

GOTO MOVLW CALL CALL

START '*' SERIAL SERIAL1 0X01 CODEDATA DIGITS,1 PORTB,7 TESTDATA '*' SERIAL SERIAL1 0X02 CODEDATA DIGITS,1 PORTB,7 TESTDATA '*' SERIAL SERIAL1 0X03 CODEDATA DIGITS,1 PORTB,7 TESTDATA 0X04 COUNTER DELAY1 PORTB,1 START COUNTER,1 TESTING1 PORTB,1 TEST2 PORTB,7 PORTA,0 i4 PORTA,1 i5

; ;* ;This will output 4 ;cause the low 4 are ;Numeric value 1 ;Save data for ;Reduce digits ;Command mode ;Redo the keypad ;* ;This will output 4 ;cause the low 4 are ;Numeric value 2 ;Save data for ;Reduce digits ;Command mode ;Redo the keypad ;* ;This will output 4 ;cause the low 4 are ;Numeric value 3 ;Save data for ;Reduce digits ;Command mode ;Redo the keypad ;The amount of ;The sample register ;Kill some time ;Re-check this bit ;False trigger, ;Re-sample 4 times ;Ditto ;Wait for release ;Ditto ;R/S set to 1 for ;Was it the first ;This is the ;Was it the second ;This is the

already high rot MOVLW MOVWF manipulation DECF register BCF GOTO scanning i2 bits only CALL already high rot MOVLW MOVWF manipulation DECF register BCF GOTO scanning i3 bits only CALL already high rot MOVLW MOVWF manipulation DECF register BCF GOTO scanning DEBOUNCE1 samples TESTING1 escape to start DECFSZ GOTO TEST2 BTFSC GOTO BSF character display BTFSC column? GOTO character (without i ) BTFSC column? GOTO character (without i ) MOVLW MOVWF CALL BTFSS GOTO MOVLW CALL MOVLW CALL

BTFSC column? GOTO character (without i ) GOTO i4 MOVLW CALL bits only CALL already high rot MOVLW MOVWF manipulation DECF register BCF GOTO scanning i5 MOVLW CALL bits only CALL already high rot MOVLW MOVWF manipulation DECF register BCF GOTO scanning i6 MOVLW CALL bits only CALL already high rot MOVLW MOVWF manipulation DECF register BCF GOTO scanning DEBOUNCE2 MOVLW samples MOVWF TESTING2 CALL BTFSS GOTO escape to start DECFSZ GOTO TEST3 BTFSC GOTO BSF character display BTFSC column? GOTO character (without i )

PORTA,2 i6 START '*' SERIAL SERIAL1 0X04 CODEDATA DIGITS,1 PORTB,7 TESTDATA '*' SERIAL SERIAL1 0X05 CODEDATA DIGITS,1 PORTB,7 TESTDATA '*' SERIAL SERIAL1 0X06 CODEDATA DIGITS,1 PORTB,7 TESTDATA 0X04 COUNTER DELAY1 PORTB,2 START COUNTER,1 TESTING2 PORTB,2 TEST3 PORTB,7 PORTA,0 i7

;Was it the third ;This is the ; ;* ;This will output 4 ;cause the low 4 are ;Numeric value 4 ;Save data for ;Reduce digits ;Command mode ;Redo the keypad ;* ;This will output 4 ;cause the low 4 are ;Numeric value 5 ;Save data for ;Reduce digits ;Command mode ;Redo the keypad ;* ;This will output 4 ;cause the low 4 are ;Numeric value 6 ;Save data for ;Reduce digits ;Command mode ;Redo the keypad ;The amount of ;The sample register ;Kill some time ;Re-check this bit ;False trigger, ;Re-sample 4 times ;Ditto ;Wait for release ;Ditto ;R/S set to 1 for ;Was it the first ;This is the

BTFSC column? GOTO character (without i ) BTFSC column? GOTO character (without i ) GOTO i7 MOVLW CALL bits only CALL already high rot MOVLW MOVWF manipulation DECF register BCF GOTO scanning i8 MOVLW CALL bits only CALL already high rot MOVLW MOVWF manipulation DECF register BCF GOTO scanning i9 MOVLW CALL bits only CALL already high rot MOVLW MOVWF manipulation DECF register BCF GOTO scanning DEBOUNCE3 MOVLW samples MOVWF TESTING3 CALL BTFSS GOTO escape to start DECFSZ GOTO TEST4 BTFSC GOTO BSF character display

PORTA,1 i8 PORTA,2 i9 START '*' SERIAL SERIAL1 0X07 CODEDATA DIGITS,1 PORTB,7 TESTDATA '*' SERIAL SERIAL1 0X08 CODEDATA DIGITS,1 PORTB,7 TESTDATA '*' SERIAL SERIAL1 0X09 CODEDATA DIGITS,1 PORTB,7 TESTDATA 0X04 COUNTER DELAY1 PORTB,3 START COUNTER,1 TESTING3 PORTB,3 TEST4 PORTB,7

;Was it the second ;This is the ;Was it the third ;This is the ; ;* ;This will output 4 ;cause the low 4 are ;Numeric value 7 ;Save data for ;Reduce digits ;Command mode ;Redo the keypad ;* ;This will output 4 ;cause the low 4 are ;Numeric value 8 ;Save data for ;Reduce digits ;Command mode ;Redo the keypad ;* ;This will output 4 ;cause the low 4 are ;Numeric value 9 ;Save data for ;Reduce digits ;Command mode ;Redo the keypad ;The amount of ;The sample register ;Kill some time ;Re-check this bit ;False trigger, ;Re-sample 4 times ;Ditto ;Wait for release ;Ditto ;R/S set to 1 for

BTFSC column? GOTO character (without i ) BTFSC column? GOTO character (without i ) BTFSC column? GOTO character (without i ) GOTO triggered,check again ix MOVLW CALL bits only CALL already high rot MOVLW MOVWF manipulation DECF register BCF GOTO scanning i0 MOVLW CALL bits only CALL already high rot MOVLW MOVWF manipulation DECF register BCF GOTO scanning i# MOVLW CALL bits only CALL already high rot MOVLW MOVWF manipulation DECF register BCF GOTO scanning

PORTA,0 ix PORTA,1 i0 PORTA,2 i# START '*' SERIAL SERIAL1 0X2A CODEDATA DIGITS,1 PORTB,7 TESTDATA '*' SERIAL SERIAL1 0X00 CODEDATA DIGITS,1 PORTB,7 TESTDATA '*' SERIAL SERIAL1 0X23 CODEDATA DIGITS,1 PORTB,7 TESTDATA

;Was it the first ;This is the ;Was it the second ;This is the ;Was it the third ;This is the ;Wasn't ;* ;This will output 4 ;cause the low 4 are ;ASCII symbol * ;Save data for ;Reduce digits ;Command mode ;Redo the keypad ;* ;This will output 4 ;cause the low 4 are ;Numeric value 0 ;Save data for ;Reduce digits ;Command mode ;Redo the keypad ;* ;This will output 4 ;cause the low 4 are ;ASCII symbol # ;Save data for ;Reduce digits ;Command mode ;Redo the keypad

;********************************************************************* **************** ; OUTCOMES *

;********************************************************************* **************** LOCKED BCF BSF MOVLW CALL CALL already high rot MOVLW shift off CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot BSF MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot BCF MOVLW CALL bits only CALL already high rot BSF MOVLW CALL bits only CALL already high rot MOVLW 'O' ;O SERIAL1 ;cause the low 4 are PORTB,7 'C' SERIAL ;Character mode ;C ;This will output 4 SERIAL1 ;cause the low 4 are PORTB,7 0XC6 SERIAL ;Command mode ;Address 45 ;This will output 4 SERIAL1 ;cause the low 4 are 'G' SERIAL ;G ;This will output 4 SERIAL1 ;cause the low 4 are 'N' SERIAL ;N ;This will output 4 SERIAL1 ;cause the low 4 are 'O' SERIAL ;O ;This will output 4 SERIAL1 ;cause the low 4 are 'R' SERIAL ;R ;This will output 4 SERIAL1 ;cause the low 4 are PORTB,7 'W' SERIAL ;Character mode ;W ;This will output 4 SERIAL1 ;cause the low 4 are 0X86 SERIAL ;Address 6 ;This will output 4 SERIAL1 ;cause the low 4 are SERIAL ;This will output 4 0X06 ;Increment display PORTB,7 PORTA,4 0X01 SERIAL SERIAL1 ;Command mode ;Red LED on ;Clear display ;This will output 4 ;cause the low 4 are

bits only

CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot BCF MOVLW MOVWF MOVLW CALL CALL already high rot CALL MOVLW CALL bits only CALL already high rot CALL DECFSZ flashes by 1 GOTO flash on and off BCF MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot BCF DECFSZ attempt reached ONE GOTO BSF BCF MOVLW CALL CALL already high rot MOVLW CALL bits only CALL already high rot BSF

SERIAL SERIAL1 'D' SERIAL SERIAL1 'E' SERIAL SERIAL1 PORTB,7 0X0A FLASH1 0X08 SERIAL SERIAL1 LONGDELAY 0X0C SERIAL SERIAL1 LONGDELAY FLASH1,1 FLASH PORTB,7 0X01 SERIAL SERIAL1 0XC0 SERIAL SERIAL1 PORTA,4 COUNTER1,1 ZERO PORTA,4 PORTB,7 0X01 SERIAL SERIAL1 0X85 SERIAL SERIAL1 PORTB,7

;This will output 4 ;cause the low 4 are ;D ;This will output 4 ;cause the low 4 are ;E ;This will output 4 ;cause the low 4 are ;Command mode ;Flash 10 times ;Flashing counter ;Display off ;This will output 4 ;cause the low 4 are ;Kill a long time ;Display on ;This will output 4 ;cause the low 4 are ;Kill a long time ;Reduce amount of ;Make the display ;Command mode ;Clear display ;This will output 4 ;cause the low 4 are ;Address 40 ;This will output 4 ;cause the low 4 are ;Red LED off ;Count if max ;Re-ask for the code ;Red LED on ;Command mode ;Clear display ;This will output 4 ;cause the low 4 are ;Address 05 ;This will output 4 ;cause the low 4 are ;Character mode

FLASH bits only

bits only

MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot BCF MOVLW CALL bits only CALL already high rot BSF MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot MOVLW CALL bits only

'L' SERIAL SERIAL1 'O' SERIAL SERIAL1 'C' SERIAL SERIAL1 'K' SERIAL SERIAL1 'E' SERIAL SERIAL1 'D' SERIAL SERIAL1 PORTB,7 0XC0 SERIAL SERIAL1 PORTB,7 'U' SERIAL SERIAL1 's' SERIAL SERIAL1 'e' SERIAL SERIAL1 ' ' SERIAL SERIAL1 'M' SERIAL

;L ;This will output 4 ;cause the low 4 are ;O ;This will output 4 ;cause the low 4 are ;C ;This will output 4 ;cause the low 4 are ;K ;This will output 4 ;cause the low 4 are ;E ;This will output 4 ;cause the low 4 are ;D ;This will output 4 ;cause the low 4 are ;Command mode ;Address 40 ;This will output 4 ;cause the low 4 are ;Character mode ;U ;This will output 4 ;cause the low 4 are ;s ;This will output 4 ;cause the low 4 are ;e ;This will output 4 ;cause the low 4 are ; ;This will output 4 ;cause the low 4 are ;M ;This will output 4

CALL already high rot MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot TWO bits only CALL already high rot MOVLW GOTO BCF MOVLW CALL

SERIAL1 'a' SERIAL SERIAL1 's' SERIAL SERIAL1 't' SERIAL SERIAL1 'e' SERIAL SERIAL1 'r' SERIAL SERIAL1 ' ' SERIAL SERIAL1 'C' SERIAL SERIAL1 'o' SERIAL SERIAL1 'd' SERIAL SERIAL1 'e' SERIAL SERIAL1 $ PORTB,7 0X01 SERIAL SERIAL1 0X82

;cause the low 4 are ;a ;This will output 4 ;cause the low 4 are ;s ;This will output 4 ;cause the low 4 are ;t ;This will output 4 ;cause the low 4 are ;e ;This will output 4 ;cause the low 4 are ;r ;This will output 4 ;cause the low 4 are ; ;This will output 4 ;cause the low 4 are ;C ;This will output 4 ;cause the low 4 are ;o ;This will output 4 ;cause the low 4 are ;d ;This will output 4 ;cause the low 4 are ;e ;This will output 4 ;cause the low 4 are ; ;Command mode ;Clear display ;This will output 4 ;cause the low 4 are ;Address 02

CALL bits only CALL already high rot BSF BSF MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot MOVLW CALL bits only CALL already high rot

SERIAL SERIAL1 PORTA,3 PORTB,7 'D' SERIAL SERIAL1 'e' SERIAL SERIAL1 '-' SERIAL SERIAL1 'A' SERIAL SERIAL1 'c' SERIAL SERIAL1 't' SERIAL SERIAL1 'i' SERIAL SERIAL1 'v' SERIAL SERIAL1 'a' SERIAL SERIAL1 't' SERIAL SERIAL1 'e' SERIAL SERIAL1

;This will output 4 ;cause the low 4 are ;Green LED on ;Character mode ;D ;This will output 4 ;cause the low 4 are ;e ;This will output 4 ;cause the low 4 are ;;This will output 4 ;cause the low 4 are ;a ;This will output 4 ;cause the low 4 are ;c ;This will output 4 ;cause the low 4 are ;t ;This will output 4 ;cause the low 4 are ;i ;This will output 4 ;cause the low 4 are ;v ;This will output 4 ;cause the low 4 are ;a ;This will output 4 ;cause the low 4 are ;t ;This will output 4 ;cause the low 4 are ;e ;This will output 4 ;cause the low 4 are

MOVLW CALL bits only

'd' SERIAL

;d ;This will output 4

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 lcdRS lcdE equ 4h equ 5h

; RB2 = LCD RW pin ; RB4 = LCD RS pin ; 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 clrf TRISA clrf TRISB ; RAM Page 1

clrf TRISC clrf TRISD clrf TRISE ; ; ------------------------; SET ANALOG/DIGITAL INPUTS ; ------------------------; movlw b'00000110' movwf ADCON1 ; = all digital

bcf STATUS,RP0

movlw 20h movwf DelayH clrf DelayL PUPD decfsz DelayL goto PUPD decfsz DelayH goto PUPD

; 25mS powerup delay @ 4MHz ; data sheet says 15mS

call Control ;

; initialize display

; ----------------------------------------------------; DISPLAY THE MESSAGE WHEN THE BUTTON ON RA3 IS PRESSED ; ----------------------------------------------------;

MnLoop

clrf MessPt ; line 1

movlw 0x80 call LCDins Loop1 call TheText xorlw 0h btfsc STATUS,Z goto DoLine2

call LCDout incf MessPt goto Loop1

DoLine2

incf MessPt ; line 2

movlw 0xC0 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 call LCDins movlw 38h call LCDins movlw 38h call LCDins movlw .6 call LCDins movlw 0ch call LCDins ; (128) display initialisation ; output to display ; page 45 of the data sheet ; output to display ; two line ; output to display ; increment display ; output to display ; display = on, cursor = off ; output to display

movlw .1 call LCDins return ;

; clear display ; output to display

; ----------------------------; OUTPUT 1 DATA BYTE TO DISPLAY ; ----------------------------; LCDout movf DisData,w movwf PORTD bsf PORTB,lcdRS call Clock bsf PORTB,lcdE call Clock bcf PORTB,lcdE call Clock bcf PORTB,lcdRS bcf STATUS,RP0 return ; ; -----------------------------------; OUTPUT 1 INSTRUCTION BYTE TO DISPLAY ; -----------------------------------; LCDins movf DisData,w movwf PORTD bcf PORTB,lcdRS ; (4) Write instruction to display ; (5) ; ram page 0 ; (5) ; (5) enable ; (4) Write data to display

call Clock bsf PORTB,lcdE call Clock bcf PORTB,lcdE call Clock ; (5) ; (5) enable

clrf DelayL movlw 8h movwf DelayH ctlp1 decfsz DelayL goto ctlp1 decfsz DelayH goto ctlp1 ; about 6mS delay @ 4MHz

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 nop $+1

;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 ; movlw d'32' ; movwf LCDByte CALL LCDBYTE move back one wipe the current char

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 ; ;---------------------------------------------------------------------; ; ; ; ; ; ; ; ; pfd ; ; ; ; ; ; ; gnd ; ; gnd ; (9) 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 [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 4 - RS 7 - D0 11 - D4 2 - Vcc V+ 3 - contrast 10K pot V+ & 6 - E RA1 PIC(18) 9 - D2 gnd 10 - D3 13 - D6 RB2 (8) 14 - D7

RA0 PIC(17) 5 - RW gnd gnd 8 - D1 gnd RB0 (6) 12 - D5 RB1 (7)

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 ; Strobe the "E" Bit

EStrobe MACRO bsf E bcf E ENDM CBLOCK 0CH sec sec10 mins min10 hr hr10 highlim w_temp

; ; ; ; ; ; ; ;

seconds digit 10's of second digit minutes digit 10's of minutes digit hours digit 10's of hours digit high limit + 1 of digit holds W during interrupt

status_temp fsr_temp Dlay working working ptr Temp bin oset oldtime cntmsec isrcnt ENDC ORG 0 goto main ORG 4 goto isr

; ; ; ; ; ; ; ; ; ; ;

holds STATUS during interrupt holds FSR during interrupt 8 Bit Delay Variable working flag 0 not working, 1 used in displaying message a temporary variable a temporary variable offset of time register holds last value of sec used in counting milliseconds used in isr to stretch time to 1 sec

; start at location 0 ; jump over to main routine

; 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 goto restore movlw D'125' movwf isrcnt movf working, f btfsc STATUS, Z ; count down to zero before incr. ; reset isr count ; check working flag ; if not zero then increment time

goto restore routine movlw sec movwf FSR incf INDF, f movlw sec subwf FSR, W call sethi subwf INDF, W btfss STATUS, Z goto restore clrf INDF incf FSR, f goto newdigit swapf status_temp,W movwf STATUS swapf fsr_temp,W movwf FSR swapf w_temp,f swapf w_temp,W bcf INTCON,T0IF retfie

; else get out of interrupt ; point at sec register ; current digit up one ; get difference, sec and FSR ; ; ; ; ; use to get high limit + 1 reached that number yet? skip over if yes else exit isr set current digit to 0 ; point at next digit ; no, increment the next digit ; ; ; ; ; ; ; ; get original status back into status register get original fsr back into status register old no flags trick again to restore W clear the TMR0 interrupt flag finished reset GIE

newdigit:

restore:

;---------------------------------------------------------------------; ; Initialize the ports ; ;---------------------------------------------------------------------; init: clrf PORTA clrf PORTB movlw B'00010000' tris PORTA movlw B'00000000' tris PORTB movlw B'00000011' ; ; ; ; ; ; ; RA4 input, others outputs all outputs on port B pull-ups enabled prescaler assigned to TMR0 prescaler set to 1:16 rolls over each 125th second zero out all registers

option movlw 0 movwf hr10 movwf hr movwf min10 movwf mins movwf sec10 movwf sec clrf working movlw B'10100000' cleared movwf INTCON return ;---------------------------------------------------------------------;

; ;

working flag to zero GIE set T0IE set, T0IF

; 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 character SendCHAR ; 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 call movf bcf call return

RS NybbleOut Temp, w RS NybbleOut

; ;

RS = 0 Send the Low Nybble

;---------------------------------------------------------------------; ; 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 letter OutLoop: 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' btfss STATUS,Z goto micro4 return

; ; ;

subtract 1 from 'W' skip when you reach zero more loops

Dlay5: msec250: nmsec: msecloop:

movlw 5 ; delay for 5 milliseconds goto $ + 2 movlw D'250' ; delay for 250 milliseconds ;*** N millisecond delay routine *** movwf cntmsec ; delay for N (in W) millisec 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 ; overhead in and out ignored

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

return turnoff: clrf working call waitup return ; working set to zero ; wait for button to be released

;---------------------------------------------------------------------; ; The Main routine ; ;---------------------------------------------------------------------; main: call init ; initialize ports, set up timer call initlcd ; initialize the LCD movlw 0 ; display 'Working Time:' call OutMessage ckbutton: ; 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

You might also like