georgiod9
Newbie level 4
Hello People,
I am new to this forum and to programming PIC microcontrollers. I am facing a problem with interfacing a 4x3 keypad matrix using the interrupt method rather than polling. I need this interrupt method for my specific application as I do not want the Microcontroller to waste time and processing power trying to do a job which can be done easier.
I have written the following C code using MikroC PRO for Pic. Moreover, I have tried simulating it with Proteus, so i am pretty sure my code has something wrong. Never mind the RTC DS1307 in the Proteus. Please any help would be much appreciated; I have been trying to solve this issue ever since 5 days ago and I haven't been sleeping doing research on other projects and ways to go around this issue.
Thanks in advance.
Attached is a compressed folder with the code files and the proteus simulation files.
I am new to this forum and to programming PIC microcontrollers. I am facing a problem with interfacing a 4x3 keypad matrix using the interrupt method rather than polling. I need this interrupt method for my specific application as I do not want the Microcontroller to waste time and processing power trying to do a job which can be done easier.
I have written the following C code using MikroC PRO for Pic. Moreover, I have tried simulating it with Proteus, so i am pretty sure my code has something wrong. Never mind the RTC DS1307 in the Proteus. Please any help would be much appreciated; I have been trying to solve this issue ever since 5 days ago and I haven't been sleeping doing research on other projects and ways to go around this issue.
Thanks in advance.
Code:
unsigned short kp;
int flag; //Flag which determines to which row the
//keypress resides
//Keypad Connections
sbit COL1 at RA0_bit;
sbit COL2 at RA1_bit;
sbit COL3 at RA2_bit;
sbit ROW1 at RB4_bit;
sbit ROW2 at RB5_bit;
sbit ROW3 at RB6_bit;
sbit ROW4 at RB7_bit;
//End Keypad connections
//LCD Connections
sbit LCD_RS at RD0_bit;
sbit LCD_EN at RD1_bit;
sbit LCD_D4 at RD4_bit;
sbit LCD_D5 at RD5_bit;
sbit LCD_D6 at RD6_bit;
sbit LCD_D7 at RD7_bit;
sbit LCD_RS_Direction at TRISD0_bit;
sbit LCD_EN_Direction at TRISD1_bit;
sbit LCD_D4_Direction at TRISD4_bit;
sbit LCD_D5_Direction at TRISD5_bit;
sbit LCD_D6_Direction at TRISD6_bit;
sbit LCD_D7_Direction at TRISD7_bit;
// End LCD module connections
char text[6];
void my_keypad(); //This function allows to set a column of the
//keypad while clearing others
void main()
{
INTCON = 0x08; //Enable RBIF bit
TRISB = 0xF0; //Set RB4-RB7 as inputs to mcu
TRISA = 0X00; //Set RA0-RA2 as outputs from mcu
lcd_init();
lcd_cmd(_LCD_CURSOR_OFF);
lcd_cmd(_LCD_CLEAR);
lcd_out(1,1,"hello"); //just a test for the lcd
while(1)
{
my_keypad();
if(flag == 1) //If we have a keypress on row 1
{
if(PORTA.B0) //number value:
kp = 49; //1 ---> 49 in ASCII
else if(PORTA.B1)
kp = 50; //2 ---> 50 in ASCII
else if(PORTA.B2)
kp = 51; //3 ---> and so on...
}
else if(flag == 2) //If we have a keypress on row 2
{
if(PORTA.B0) //If Column1 == 1
kp = 52; //4
else if(PORTA.B1) //If Column2 == 1
kp = 53; //5
else if(PORTA.B2) //If Column 3 == 1
kp = 54; //6
}
else if(flag == 3) //If we have a keypress on row 3
{
if(PORTA.B0)
kp = 55; //7
else if(PORTA.B1)
kp = 56; //8
else if(PORTA.B2)
kp = 57; //9
}
else if(flag == 4) //If we have a keypress on row 4
{
if(PORTA.B0)
kp = 42; //*
else if(PORTA.B1)
kp = 48; //0
else if(PORTA.B2)
kp = 35; //#
}
lcd_out(1,1,kp);
}
}
void interrupt()
{
if(INTCON.RBIF) //checks for an interrupt flag on port B
{
if(PORTB.F4 == 0) //check the value on pin B4 or Row 1 of keypad
flag = 1; //flag = 1 means we have a keypress on row 1
else if(PORTB.F5 == 0) //check the value on pin B5 or Row 2 of keypad
flag = 2; //flag = 2 means we have a keypress on row 2
else if(PORTB.F6 == 0) //check the value on pin B6 or Row 3 of keypad
flag = 3; //flag = 3 means we have a keypress on row 3
else if(PORTB.F7 == 0) //check the value on pin B7 or Row 4 of keypad
flag = 4; //flag = 4 means we have a keypress on row 4
}
INTCON.RBIF = 0; //Reset interrupt flag on port B
}
void my_keypad() //function that sets and resets the columns
//columns are outputs of mcu
//rows are inputs to mcu, rows are connected
//to pulldown resistors
{
//Test column 1
PORTA.F0 = 1; //Set Column 1 to 1
PORTA.F1 = 0; //Set Column 2 to 0
PORTA.F2 = 0; //Set Column 3 to 0
DELAY_MS(20);
//Test column 2
PORTA.F0 = 0; //Set Column 1 to 0
PORTA.F1 = 1; //Set Column 2 to 1
PORTA.F2 = 0; //Set Column 3 to 0
DELAY_MS(20);
//Test column 3
PORTA.F0 = 0; //Set Column 1 to 0
PORTA.F1 = 0; //Set Column 2 to 0
PORTA.F2 = 1; //Set Column 3 to 1
delay_ms(20);
}
Attached is a compressed folder with the code files and the proteus simulation files.