Skip to content

Instantly share code, notes, and snippets.

@marioIncandeza
Created September 25, 2015 22:50
Show Gist options
  • Save marioIncandeza/6651ca2a40490370e925 to your computer and use it in GitHub Desktop.
Save marioIncandeza/6651ca2a40490370e925 to your computer and use it in GitHub Desktop.
;This code checks to see which button is pressed on the 4x4 keypad and displays it on an LCD
;It formats the numbers like a phone number and dials after 10 entries
;hardware request:SW S4 ON ,S6 ON,S5 5-6 bits ON,the others OFF
;******************************************************
;PIC Configuration for PIC16F887
#include "p16F887.inc"
; CONFIG1
; __config 0x2032
__CONFIG _CONFIG1, _FOSC_HS & _WDTE_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_ON & _CPD_ON & _BOREN_OFF & _IESO_OFF & _FCMEN_OFF & _LVP_OFF
; CONFIG2
; __config 0x3FFF
__CONFIG _CONFIG2, _BOR4V_BOR40V & _WRT_OFF
;******************************************************
;************************define user registers***************************
BUFFER EQU 20H ;keep the result of read PORT
KEY EQU 21H ;press key code of the start key in the same row
VALUE EQU 22H ;key code
LASTVAL EQU 23H ;keeps track of the last key code
COUNT EQU 24H ;counts keypresses
INDEX EQU 25H ;used in DIALING
CURCHAR EQU 26H ;used in DIALING
#DEFINE RS PORTA,1 ;LCD bits connnected to PORTA
#DEFINE RW PORTA,2
#DEFINE E PORTA,3
;*******************program entrance address***********************
ORG 000H ;reset address
NOP ;the nop instruction of ICD require
GOTO MAIN ;jump to main program address
ORG 008H
;********************DATA TABLE***************************
TABLE
ADDWF PCL,1 ;PC add offset for table
RETLW '0' ;all my numbers and special characters
RETLW '1'
RETLW '2'
RETLW '3'
RETLW '4'
RETLW '5'
RETLW '6'
RETLW '7'
RETLW '8'
RETLW '9'
RETLW '('
RETLW ')'
RETLW '-'
TABLE2
ADDWF PCL,1 ;Dialing...
RETLW ' '
RETLW ' '
RETLW 'D'
RETLW 'i'
RETLW 'a'
RETLW 'l'
RETLW 'i'
RETLW 'n'
RETLW 'g'
RETLW '.'
RETLW '.'
RETLW '.'
RETLW 00H
;*******************main program****************************
MAIN
BANKSEL TRISC ;select bank to access TRIS registers
CLRF TRISD ;make PORTD all outputs
CLRF TRISA ;PORTA OUTPUT
MOVLW 0FH
MOVWF TRISC ;PORTC low 4 bits INPUT,high 4 bits OUTPUT
BANKSEL ANSEL ; All digital mode
CLRF ANSEL
CLRF ANSELH
BANKSEL PORTA ;clearing things out
CLRF PORTA
CLRF PORTD
MOVLW 0FFH
MOVWF VALUE ;I initially set this to 255, a value unattainable by a keypress
CLRF COUNT
MOVLW 08H ;turn the screen off
MOVWF PORTD ;i had to do this to clear the screen after a reset
CALL SENDCOM
MOVLW 01H
MOVWF PORTD ;clr screen
CALL SENDCOM ;write command to LCD
MOVLW 38H ;38
MOVWF PORTD ;8 bits 2 lines 5*7 mode. Function set.
CALL SENDCOM
MOVLW 0CH ;display on,cursor off,blink off.(0C)
MOVWF PORTD
CALL SENDCOM
MOVLW 06H ;character not move,cursor rotate right.
MOVWF PORTD
CALL SENDCOM
MOVLW 80H
MOVWF PORTD ;Move cursor to top of first line
CALL SENDCOM
LOOP
MOVLW 0AH ;have 10 numbers been entered?
XORWF COUNT,0
BTFSC STATUS,Z
CALL DIALING ;if so, dial!
CALL CHECKROWS ;call subroutine to check which row has a pressed key
CALL CHANGE ;call subroutine to decode value received into key value
MOVF LASTVAL,0 ;is value equal to last value?
XORWF VALUE,0
BTFSC STATUS,Z ;if so, start back over at loop
GOTO LOOP
CALL DISPLAY ;call display subroutine to put value on LCD
CALL DELAY ;slowing things down a little
GOTO LOOP ;infinite loop
;*******************key scan subprogram*************************
CHECKROWS
MOVF VALUE,0 ;move value into lastval
MOVWF LASTVAL
CLRF KEY
CLRF VALUE
COMF VALUE,1 ;i clear and complement to make this 255
;if you're still holding down the button,
;value will quickly be set back to the value of whatever
;button you happen to be holding and the bit test
;in the main loop will prevent that from being displayed
;or counted
CHECKROW1
MOVLW B'11101111'
MOVWF PORTC ;RC4 OUTPUT low,the others high
NOP ;wait for input to settle
MOVF PORTC,0 ;read PORT C to W
ANDLW 0FH ;mask high 4 bits
XORLW 0FH ;check if a key is pressed(if PORT C is not 0F)
BTFSC STATUS,Z
GOTO CHECKROW2 ;no key pressed in row 1, check 2nd row
MOVF PORTC,0 ;key is pressed,store PORTC state in buffer
MOVWF BUFFER
MOVLW 0H ;pressed key is at the first line, key offset is 0
MOVWF KEY
GOTO SCAN_END ;jump to scan end
CHECKROW2
MOVLW B'11011111'
MOVWF PORTC ;RC5 OUTPUT low,the others high
NOP ;wait for input to settle
MOVF PORTC,0 ;read PORT C to W
ANDLW 0FH ;mask high 4 bits
XORLW 0FH ;check if a key is pressed
BTFSC STATUS,Z
GOTO CHECKROW3 ;no key pressed in row 2
MOVFW PORTC ;have,temporary keep C PORT state
MOVWF BUFFER
MOVLW 4H ;pressed key is in second row, key offset is 4
MOVWF KEY
GOTO SCAN_END ;jump to scan end
CHECKROW3
MOVLW B'10111111'
MOVWF PORTC ;RC6 OUTPUT low,the others high
NOP
MOVF PORTC,0 ;read PORT C to W
ANDLW 0FH ;mask high 4 bits
XORLW 0FH ;check if a key pressed
BTFSC STATUS,Z
GOTO CHECKROWS ;no key pressed in row 3
MOVFW PORTC ;have,temporary keep C PORT state
MOVWF BUFFER
MOVLW 8H ;pressed key is in third row, key offset is 8
MOVWF KEY
GOTO SCAN_END ;jump to scan end
NOKEY ;if no key has been pressed, we just keep checking
GOTO CHECKROWS ;this will also reset lastval to 255 so you can dial the same
;number twice in a row
SCAN_END
RETURN ;program return
CHANGE
CLRF VALUE ;clear key code register
BTFSS BUFFER,3 ;judge if read RC3 is 0
GOTO CHANG1 ;yes,jump to CHANG1
BTFSS BUFFER,2 ;no,judge if read RC2 is 0
GOTO CHANG2 ;yes,jump to CHANG2
BTFSS BUFFER,1 ;no,judge if read RC1 is 0
GOTO CHANG3 ;yes,jump to CHANG3
BTFSS BUFFER,0 ;no,judge if read RC0 is 0
GOTO CHANG4 ;yes,jump to CHANG4
GOTO CHANG_END ;no,jump to program end
CHANG1
MOVLW 0H
MOVWF VALUE ;pressed key is at the first row
GOTO CHANG_END
CHANG2
MOVLW 1H
MOVWF VALUE ;pressed key is at the second row
GOTO CHANG_END
CHANG3
MOVLW 2H ;pressed key is at the third row
MOVWF VALUE
GOTO CHANG_END
CHANG4
MOVLW 3H ;pressed key is at the fourth row
MOVWF VALUE
CHANG_END
MOVF KEY,0 ;the line code add the row code is the key code
ADDWF VALUE,1
CLRF KEY
CLRF BUFFER
RETURN ;program return
;********************display subprogram*************************
DISPLAY
MOVLW 0AH ;don't display anything if right two buttons on row 3 are pressed
XORWF VALUE,0
BTFSC STATUS,Z
RETURN
MOVLW 0BH
XORWF VALUE,0
BTFSC STATUS,Z
RETURN
MOVLW 00H
XORWF COUNT,0 ;is this the first number dialed?
BTFSC STATUS,Z
CALL FIRSTENTRY
MOVLW 06H
XORWF COUNT,0
BTFSC STATUS,Z
CALL DASH ;would you like a dash?
MOVF VALUE,0
CALL TABLE
CALL CHARTOLCD
MOVLW 02H
XORWF COUNT,0
BTFSC STATUS,Z
CALL CLOSEPAREN ;was that the third number? i'll close the parentheses
INCF COUNT,1 ;count +1
RETURN
;*******************delay subprogram******************************
DELAY ;Nested loops of counters decrementing to slow output
MOVLW 0FFH ;
MOVWF 20H ;send external loop count 0ffh to 20h
LP0
MOVLW 09FH ;
MOVWF 21H ;send internal loop count 0ffh to 21h
LP1
DECFSZ 21H,1 ;decrease 21h,if 0,then jump
GOTO LP1 ;continue loop at LP1
DECFSZ 20H,1 ;decrease 20h,if 0,then jump
GOTO LP0 ;continue loop at LP0
RETURN
;******************send data to lcd.************
CHARTOLCD
MOVWF PORTD ;Writes out contents of W register to LCD via PORTD
BSF RS
BCF RW
BCF E
CALL DELAY
BSF E
RETURN
;****************send command to lcd.**************
SENDCOM ;Sends configuration commands (not data) to LCD
BCF RS
BCF RW
BCF E
CALL DELAY
BSF E
RETURN
;********************the first parenthesis*********************
FIRSTENTRY
MOVLW 0AH
CALL TABLE
CALL CHARTOLCD
RETURN
;********************the closing parenthesis*********************
CLOSEPAREN
MOVLW 0BH
CALL TABLE
CALL CHARTOLCD
RETURN
;***********************-------------------**********************
DASH
MOVLW 0CH
CALL TABLE
CALL CHARTOLCD
RETURN
;**********************now we're dialing**************************
DIALING
MOVLW 0C0H
MOVWF PORTD ;moves cursor to line 2, first position
CALL SENDCOM
CLRF INDEX ;clear offset
DIALING_A
MOVF INDEX,0 ;Put current index in W
CALL TABLE2 ;search to display next character
MOVWF CURCHAR
XORLW 00H ;check if line finished.(the last byte is 00h.)
BTFSC STATUS,Z
GOTO $+5 ;top line display finished, skip down to return
MOVFW CURCHAR
CALL CHARTOLCD ;not finished, send current character out to LCD
INCF INDEX,1 ;increment index to move to next character in table
GOTO DIALING_A ;keep going to get next character
RETURN ;Done with top line, go back
;*******************program end******************************
END
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment