Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[PIC] PIC Microcontroller LCD/Keypad Project Code Issues

Status
Not open for further replies.

Gonzoid

Newbie level 3
Joined
Nov 6, 2013
Messages
3
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
27
Hello Everyone,

I have previously created a source code that implements a 4x3 keypad and an LCD display. The idea was to have the circuit act much like a keyboard, where whatever key is pressed on the keypad is displayed on the LCD. However, when add to the hardware, the LCD would receive information from 6 of the 12 keypad buttons. The keypad routine I used I simply had copy and pasted from another source file, with a few modifications, I had made to drive LED's, and it had worked. The LCD routine I also simply copy and pasted from a source file I had made, which only displayed one message.

Here is my combined source code, in Assembly:
Code:
	#include <P16F877A.INC>	;Header File

KEY		EQU		0X20		;This is the user defined DRAM area that
COUNT	EQU		0X21		; uses the 68 bytes GPR: range from 0X0C-0X4F
MEM		EQU		0X22
TEMP	EQU		0X23
TEMP2	EQU		0X24
DVAR	EQU		0X25
FLAG	EQU		0X26
TEMP_3	EQU		0X27
TEMP_4	EQU		0X28
SAVE	EQU		0X29
INDEX	EQU		0X2A
COUNT2	EQU		0X2B
COUNT3	EQU		0X2C

		__CONFIG	0X3F72	;This is the control bits for CONFIG register

		ORG		0X0000		;RESET or WDT reset vector
		GOTO	START
		
		ORG		0X0004		;Regular INT vector

;This is the area where your interrupt service routine goes

		RETFIE

INIT
		BSF			PORTD,0				;Set E line High
		BCF			PORTD,1				;Set RS line low
		MOVLW		0X30				
		MOVWF		PORTC				;Put initialization value into LCD
		CALL		TOGGLE_E			;Short delay
		CALL		DELAY				;20 ms delay
		MOVLW		0X30				
		MOVWF		PORTC				;Put initialization value into LCD
		CALL		TOGGLE_E			;Short delay
		CALL		DELAY				;20 ms delay
		MOVLW		0X30		
		MOVWF		PORTC				;Put initialization value into LCD			
		CALL		TOGGLE_E			;Short delay
		CALL		DELAY				;20 ms delay
		MOVLW		0X38	
		MOVWF		PORTC				;Put initialization value into LCD
		CALL		TOGGLE_E			;Short delay
		CALL		DELAY				;20 ms delay
		MOVLW		0X0C
		MOVWF		PORTC				;Put initialization value into LCD
		CALL		TOGGLE_E			;Short delay
		CALL		DELAY				;20 ms delay
		MOVLW		0X01
		MOVWF		PORTC				;Put initialization value into LCD			
		CALL		TOGGLE_E			;Short delay
		CALL		DELAY				;20 ms delay
		MOVLW		0X06
		MOVWF		PORTC				;Put initialization value into LCD
		CALL		TOGGLE_E			;Short delay
		CALL		DELAY				;20 ms delay
		MOVLW		0X02
		MOVWF		PORTC				;Put initialization value into LCD
		CALL		TOGGLE_E			;Short delay
		CALL		DELAY				;20 ms delay
		BSF			PORTD,1				;Resets RS line
		RETURN							;Returns to main program 

DELAY
		MOVLW 		0X4A 				;Set X (LOOP1) to 74 count
		MOVWF 		COUNT 				;Moves 0X4A into Counter 1

LOOP1
		MOVLW 		0XFC				;Set Y (LOOP2) to 252 count
		MOVWF 		COUNT2 				;Moves 0XFC into Counter 2
LOOP2 
		DECF 		COUNT2,F 			;Decrease counter 2
		BTFSS 		STATUS,Z			;Bit check counter 2
		GOTO 		LOOP2 				;Restart loop 2
		DECF 		COUNT,F 			;Decrease counter 1
		BTFSS 		STATUS,Z 			;Bit test counter 1
		GOTO 		LOOP1 				;Restart loop 1
		RETURN							;Returns from subroutine 1

TOGGLE_E
		BCF			PORTD,0				;Clear E line
		NOP
		NOP
		NOP
		BSF			PORTD,0				;Set E line
		RETURN							;Return					

CHK_KEY
		MOVLW		0X04				;Set Count3 to 0X04
		MOVWF		COUNT3
		MOVF		PORTB,W 			;Moves input from keypad into W
		MOVWF		TEMP_4				;Save W in Temp_4

ROTATE
		RRF			TEMP_4,F			;Rotates Temp_4 right
		BTFSS		STATUS,C			;Checks for carry from rotate
		CALL		MOOP				;Calls MOOP subroutine
		INCF		INDEX,F				;Increments Index by 1
		DECFSZ		COUNT3,F			;Decreases counter until 0
		GOTO		ROTATE				;Restarts rotate subroutine
		RETURN							;Returns to main program

MOOP	
		MOVF		INDEX,W				;Moves Index into W
		MOVWF		SAVE				;Saves Index 
		CALL		DEBOUNCE			;Cakk debounce subroutine
		BSF			FLAG,0				;Sets Flag to 0
		RETURN							;Returns to Rotate

DEBOUNCE
		MOVF		PORTB,W				;Moves input from PortB into W
		MOVWF		TEMP_3				;Saves in Temp_3
		
		RRF			TEMP_3,F			;Rotates Temp_3 Right
		BTFSS		STATUS,C			;Tests C for set
		GOTO		DEBOUNCE			;Restarts Debounce routine	

		RRF			TEMP_3,F			;Rotates Temp_3 Right		
		BTFSS		STATUS,C			;Tests C for set
		GOTO		DEBOUNCE			;Restarts Debounce routine

		RRF			TEMP_3,F			;Rotates Temp_3 Right
		BTFSS		STATUS,C			;Tests C for set
		GOTO		DEBOUNCE			;Restarts Debounce routine

		RRF		 	TEMP_3,F			;Rotates Temp_3 Right
		BTFSS		STATUS,C			;Tests C for set
		GOTO		DEBOUNCE			;Restarts Debounce routine

		BSF			FLAG,0				;Set Flag 0
		RETURN							;Returns to MOOP routine.

[B]LN_TABLE                                                           ;LCD Reference Table[/B]
		MOVWF		TEMP2				;Save W in TEMP2
		MOVLW		HIGH MSG			;Reference high message
		MOVWF		PCLATH				;Update the PCH register 
		MOVF		TEMP2,W				;Get LO byte
		ADDLW		LOW MSG				;Update PCL register
		BTFSC		STATUS,C			;Check for overflows
		INCF		PCLATH,F			;Update overflow of PCH
		MOVWF		PCL
	
[B]MSG										;Letters for LCD Display
		ADDWF		PCL,F				
		RETLW		' '
		RETLW		' '
		RETLW		' '
		RETLW		'A' ;Works
		RETLW		'B' ;Works
		RETLW		'C' ;Works
		RETLW		' '
		RETLW		'D' ;Works
		RETLW		'E' ;Works
		RETLW		'F' ;Works[/B]

		RETLW		0X00				;Signature
	

START						;The starting place of the user codes

;This is the area where your main program that is the major routine and 
;  subroutine in the Assembly language format goes
	
		CLRF		FLAG
		BSF			STATUS,RP0			;Set to Bank 1
		MOVLW		0X0F				
		MOVWF		TRISB				;Moves 0X0F into TRISB (PORTB)
		MOVLW		0X00				
		MOVWF		TRISA  				;Moves 0X00 into TRISA (PORTA)
		MOVLW		0X00
		MOVWF		TRISC
		MOVLW		0X80
		MOVWF		TRISD
		BCF			STATUS,RP0	
		BCF			PORTD,1				;Clear RS for initialization
		CALL		INIT				;Run initialization

KEY_LOOP
		BTFSS		PORTD,7
		CALL		LOCK	
		CLRF		FLAG
		CALL		DELAY
		CALL		DELAY
		MOVLW		0X00
		MOVWF		INDEX		
		BCF			PORTB,7
		BSF			PORTB,6
		BSF			PORTB,5		
		CALL		CHK_KEY
		BTFSC		FLAG,0
		GOTO		CLICK

		BCF			PORTB,6
		BSF			PORTB,7
		BSF			PORTB,5
		CALL		CHK_KEY
		BTFSC		FLAG,0
		GOTO		CLICK

		BCF			PORTB,5
		BSF			PORTB,7
		BSF			PORTB,6		
		CALL		CHK_KEY
		BTFSC		FLAG,0
		GOTO		CLICK
		GOTO		KEY_LOOP

CLICK
		CLRW
		MOVWF		TEMP				;Save in TEMP
		
DISPLAY_LONG
		MOVF		TEMP,W				
		INCF		TEMP,F
CLEAR
		CLRF		FLAG
		CLRF		PORTC
		MOVF		SAVE,W
		CALL		LN_TABLE			;Calls long table
		MOVWF		PORTC				;Sets message to Port C
		IORLW		0X00				;OR message
		BTFSC		STATUS,Z			;Check for zero
		GOTO		$					;End program
		CALL		TOGGLE_E			;Short delay
		CALL		DELAY				;20ms delay
		GOTO		KEY_LOOP			;Restart loop

LOCK		
		BTFSS		PORTD,7
		GOTO		CLEARED
		RETURN


STOP
		GOTO		$
END

I have change the characters in the LCD Lookup table so that the ones blank and in parenthesis are the locations in the program that don't work, and the lettered values are the locations in the program that do display in the LCD. I have bolded this section for quick reference. I am using a PIC 16F877a microcontroller, editing using MPLAB, with 4x3 keypad and 16 pin LCD. If anyone can see any issues with my coding, please let me know.
 
Last edited:

I would like to add that I would like to have a static character that is always displayed on the left side of the LCD, and when keys are pressed on the keypad, the resulting characters are added to the right of that static character.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top