Created
September 25, 2015 22:50
-
-
Save marioIncandeza/6651ca2a40490370e925 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;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