PDA

View Full Version : PIC 16F877A Keypad interfaceded with Input and LCD as Displays Output



np123
- 14th September 2006, 00:10
I am new to PIC programming,, have been fiddling with BLINK.Bas
and managed to make the LCD show a message "LED Blinking"
just before the LED blinks.

I am using the MCS PICBasic Pro for the sake of compiling and am using the
DIY K149 Pic Micro Programmer to program my PIC16F877A.

Now I was wondering how would I be able to use the Keypad as an input
and display things on the LCD.

I am sure my question is very newbie, but if someone could explain me
how I could manage my inputs and storing into registers and then output
it to whatever port pin etc., then it would be of great help.

Thank you!
Attached Files

RussMartin
- 14th September 2006, 05:46
I started with these two which came on the disk with my meLabs LabX1 board:

keyx.bas

testx.bas

I've attached a text file for each. Remember to rename them by changing the extension to ".bas"!

np123
- 14th September 2006, 15:56
Thanks a loot.. I breezed through the keypad.bas and am so sure
my solution lies in there. I will try implementing the keypad input and LCD as
output and then the ADC soon :)
Thanx a ton u roK!

RussMartin
- 14th September 2006, 18:39
I ran across this elsewhere in this forum. You might also consider trying it.

http://www.picbasic.co.uk/forum/showthread.php?t=4640

mister_e
- 15th September 2006, 06:46
Russ,
Are your sure of your link? ;) To me it's more like a endless loop :D

np123
- 15th September 2006, 18:31
Hardware Connections:
I connected the Keypad to the Port B (0-7) not sure about which pins were
rows and which were colums but I changed connections to take care of both
cases.

Now the LCD reaches "TESTING Keypad" and then nothing happens
when I press a Key upon the dispay message " Press Key Now"

I am wondering if theres anything wrong in the Keypad routine..

Any help would be greatly appreciated.. since the next step of my
project depends greatly on getting this working and understand
whats happening..in this code

Thank you
------------------------------------


The .BAS Code




Define LOADER_USED 1
Define OSC 4
'Define LCD registers and bits
'Define LCD registers and bits
DEFINE LCD_DREG PORTC 'Define PIC port used for LCD Data lines
DEFINE LCD_DBIT 0 'LCD Data Starting Bit = Bit 0 or 4
DEFINE LCD_EREG PORTE 'Define PIC port used for E line of LCD
DEFINE LCD_EBIT 2 'Define Port pin used for E connection
'DEFINE LCD_RWREG PORTD 'Define PIC port used for RW line of LCD
'DEFINE LCD_RWBIT 0 'Define Port pin used for RW connection
DEFINE LCD_RSREG PORTD 'Define PIC port used for RS line of LCD
DEFINE LCD_RSBIT 1 'Define Port pin used for RS connection
DEFINE LCD_BITS 4 'Define the 4 bit communication mode to LCD
DEFINE LCD_LINES 4 'Define using a 4 line LCD
DEFINE LCD_COMMANDUS 2000 'Define delay time between sending LCD commands
DEFINE LCD_DATAUS 50 'Define delay time between data sent.


DEFINE KEYPAD_ROW 4 ' 4 ROW keypad
DEFINE KEYPAD_ROW_PORT PORTB ' ROW port = PORTB
DEFINE KEYPAD_ROW_BIT 4 ' ROW0 = PORTB.4
DEFINE KEYPAD_COL 4 ' 4 COL keypad
DEFINE KEYPAD_COL_PORT PORTB ' COL port = PORTB
DEFINE KEYPAD_COL_BIT 0 ' COL0 = PORTB.0
DEFINE KEYPAD_DEBOUNCEMS 200 ' debounce delay = 200 mSec
DEFINE KEYPAD_AUTOREPEAT 1 ' use auto-repeat feature

'*********Port Assignments*************************************** **********************************************

LED var PortB.2 ' Variable so we don't have to remember what port and bit it is on

' -----[ Initialize Hardware ]------------------------------------------------
TRISA = %00001111 ' Set PORTA to all input (Thermistor is on A.1)

ADCON1 = %10000100 ' Set PORTA analog and right justify result

TRISB = %00000000 ' PortB are all outputs
PORTB = %00000000 '

TRISC = %10010000 '
PORTC = %00000000 '

TRISD = %00000000 ' LCD
PortD = %00000000 '

TrisE.0 = 1
TrisE.1 = 0
PortE.1 = 0
TrisE.2 = 0
PortE.2 = 0

'Program Definitions
col Var Byte ' Keypad column
row Var Byte ' Keypad row
key Var Byte ' Key value
OPTION_REG.7 = 0 ' Enable PORTB pullups
ADCON1 = 7 ' Make PORTA and PORTE digital
'Low PORTE.2 ' LCD R/W low (write)
Pause 1000
LCDOut $FE,1,"TESTING",$FE,$C0,"KEYPAD DISPLAY"
Pause 2000
LCDOut $FE,1,"CLICK ANY KEY",$FE,$C0,"NOW..."


loop: Gosub getkey ' Get a key from the keypad
Lcdout $fe, 1, #key ' Display ASCII key number
Goto loop ' Do it forever

' SubRoutines placed after the END statement
' Subroutine to get a key from keypad

getkey:
Pause 50 ' Debounce

getkeyu:
' Wait for all keys up
PORTB = 0 ' All output pins low
TRISB = $f0 ' Bottom 4 pins out, top 4 pins in
If ((PORTB >> 4) != $f) Then getkeyu ' If any keys down, loop

Pause 50 ' Debounce

getkeyp:
' Wait for keypress
For col = 0 To 3 ' 4 columns in keypad
PORTB = 0 ' All output pins low
TRISB = (dcd col) ^ $ff ' Set one column pin to output
row = PORTB >> 4 ' Read row
If row != $f Then gotkey ' If any keydown, exit
Next col

Goto getkeyp ' No keys down, go look again

gotkey: ' Change row and column to key number 1 - 16
key = (col * 4) + (ncd (row ^ $f))
Return ' Subroutine over

End
' Subroutine over

mister_e
- 15th September 2006, 20:43
Have a look at that!
http://www.picbasic.co.uk/forum/showthread.php?t=3250

RussMartin
- 16th September 2006, 17:09
Yep, it sure does look like a loop, Steve. You posted the correct link--the one I wanted to send. Oops! Thanks for catching that, Steve.

np123
- 17th September 2006, 17:46
Could some1 explain me the algorithm of whats happening int he keypad.bas?

I ve been trying to figure out and it doesnt make a whole lot of sense to me :(

So my Kb_row_bit =0 and kb_col_bit=4 (initially)
how does the algorithm take care of the scanning from here?
I think I understood a few iterations but I am not toosure I
totally understand

Below are teh subroutines from that file that I think are managing the scanning process

Scan the Keypad
' ===============
repeat
key=0 ' no key is press
row=0 ' begin scan @ ROW0
col=0 ' COL0
kb_row_PORT=kb_row_PORT | InitialState ' set all ROW bits to 1
repeat
ROWBIT=ROW+KB_ROW_BIT ' point to a ROW bit
kb_row_PORT.0[RowBit]=0 ' clear actual ROW bit

Gosub readcol ' Read column
if KeyTemp != KeyMask then ' Any column to 0?
REPEAT ' YES
IF KeyTemp.0=0 THEN ' IF the actual column=0
key=row*KB_COL ' Calculate
key=key+col ' the
key=key+1 ' Value
row=KB_ROW ' Set maximum ROW to getout of here
@ ifndef KEYPAD_AUTOREPEAT ' If AutoRepeat is not DEFINE
repeat
Gosub readcol ' Wait until
until KeyTemp=keymask ' Key is released
@ endif
PAUSE DebounceDelay ' Debounce delay
ENDIF
keytemp=keytemp>>1 ' shift to next column bit
Col=col+1 ' go to next column
UNTIL COL=KB_COL ' COL scan Finished?
endif

kb_row_PORT.0[Rowbit]=1 ' set actual ROW bit
row=row+1 ' point to next row
until row>(KB_ROW-1)
until key!=0 ' Row scan finished?
RETURN ' any key pressed?

ReadCol:
KeyTemp=kb_col_PORT>>kb_col_Bit ' Read Column state
KeyTemp=KeyTemp & kEYMASK ' Keep only wanted bits
return