PDA

View Full Version : KEYPAD and Interrupt on Changing PORTB



Mostafa
- 17th December 2006, 15:31
hi

i want to implement a keypad using PicBasic PRO, and i want to use the interrupt on change of PORTB. i am using 16F877 and i can't use "polling routine" in this project with , also i can't use any Keypad IC (like 74C922).

i wrote a program and i attach its PROTEUS file its schematic.



'************************************************* ***************
'* Name : PORTB_CHANGE.BAS *
'* Author : Mostafa Taghavi Kani *
'* Notice : Copyright (c) 2006 Embedded Technology *
'* : All Rights Reserved *
'* Date : 2006/12/14 *
'* Version : 1.0 *
'* Notes : *
'************************************************* ***************

define OSC 4
'PIC 16F877

DEFINE LCD_DREG PORTA
DEFINE LCD_DBIT 0
DEFINE LCD_RSREG PORTA
DEFINE LCD_RSBIT 4
DEFINE LCD_EREG PORTE
DEFINE LCD_EBIT 0
DEFINE LCD_BITS 4
DEFINE LCD_LINES 2

GIE VAR INTCON.7
PEIE VAR INTCON.6
T0IE VAR INTCON.5
INTE VAR INTCON.4
RBIE VAR INTCON.3
T0IF VAR INTCON.2
INTF VAR INTCON.1
RBIF VAR INTCON.0

RBPU VAR OPTION_REG.7
INTEDG VAR OPTION_REG.6
T0CS VAR OPTION_REG.5
T0SE VAR OPTION_REG.7
PSA VAR OPTION_REG.3
PS2 VAR OPTION_REG.2
PS1 VAR OPTION_REG.1
PS0 VAR OPTION_REG.0

i VAR BYTE
x VAR BYTE
ROW VAR BYTE
COL VAR BYTE
J VAR BYTE
R VAR BIT
C VAR BIT

TRISB=%11110000 : 'PORTB=%11111111
TRISD=%00000000
i=0

INTCON = %10001000
RBPU=0

ON INTERRUPT GOTO TEST

MAIN:
IF I==0 THEN
LCDOUT $FE,1,"PRESS ANY KEY!"
ELSE
LCDOUT $FE,1,"(ROW,COLUMN)=","(",#R,",",#C,")"
ENDIF

PORTB=(PORTB & %11110010)
PAUSE 20
PORTB=(PORTB & %11110100)
PAUSE 20
PORTB=(PORTB & %11111000)
PAUSE 20
GOTO MAIN

DISABLE
TEST:
@ MOVF PORTB,W 'IMPORTANT:reads PORTB and moves the value to W register!!!
ROW=(PORTB & %11110000)
COL=(PORTB & %00001110)
SELECT CASE ROW
CASE %00010000
R=1
CASE %00100000
R=2
CASE %01000000
R=3
CASE %10000000
R=4
END SELECT

SELECT CASE COL
CASE %00000010
C=1
CASE %00000100
C=2
CASE %00001000
C=3
END SELECT
i=i+1
RBIF=0
RESUME
ENABLE
END


thanks in advance,
with best regards.

mister_e
- 18th December 2006, 08:32
Here's something to play with


DEFINE LCD_DREG PORTA
DEFINE LCD_DBIT 0
DEFINE LCD_RSREG PORTA
DEFINE LCD_RSBIT 4
DEFINE LCD_EREG PORTE
DEFINE LCD_EBIT 0
DEFINE LCD_BITS 4
DEFINE LCD_LINES 2

include "keypad.bas"

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 3 ' 3 COL keypad
DEFINE KEYPAD_COL_PORT PORTB ' COL port = PORTB
DEFINE KEYPAD_COL_BIT 1 ' COL0 = PORTB.1
DEFINE KEYPAD_DEBOUNCEMS 50 ' debounce delay = 50 mSec
DEFINE SCAN_ONCE 1

OPTION_REG.7=0 ' Enable internal crap pull-up :D
ADCON1=7 ' disable ADCs
PORTB = 0 '
TRISB = %11110000 '

ByteA var byte '

INTCON = %10001000 ' Enable global interrupt
' Enable interrupt on PORTB change
on interrupt goto KeypadInt
CLEAR

Init:
lcdout $FE,1,"Press any Key"
Start:
if Bytea then
LCDOUT $FE,1,"Key=",dec bytea
bytea=0
pause 1000
goto init
endif
goto start

disable
KeypadINT:
@ READKEYPAD _ByteA
TRISB=%11110000
PORTB=0
INTCON.0=0
resume
enable

you'll find the Keypad.Bas file in attachement. Don't forget to include it in the same directory.

Enjoy

Mostafa
- 18th December 2006, 09:10
THANKS master Steve :)
it work properly.
with best regards, Mostafa