|
|
View previous topic :: View next topic |
Author |
Message |
bideshm
Joined: 03 Dec 2007 Posts: 9 Location: India
|
Handle port B interrupt and show data on 7segments LED |
Posted: Wed Dec 16, 2009 4:56 am |
|
|
Hi All,
I am trying to handle port B interrupt which is written for 4*4 matrix keypad and simultaneously display enter value on 12 seven segments LED.
I used the B0 to B3 port pin for column and B4 to B7 for row. Please look at the below code.
Code: | //Device file
#include <18F452.h>
#fuses HS, NOWDT, NOLVP, NOBROWNOUT, NOPROTECT, PUT
#use delay(clock=4000000)
#use RS232 (baud=9600, parity=N, bits=8, xmit=PIN_C6, rcv=PIN_C7, errors, stream=RS232)
BYTE bPressedKey;
BYTE bKeyArrangement [4][3] = {'1', '2', '3',
'4', '5', '6',
'7', '8', '9',
'R', '0', 'O'};
//Functions prototypes
void KeyPadController( void );
BYTE GetPressedKey( void );
void ScanColumn();
BYTE GetPressedKey( void )
{
byte changes;
int8 current;
current = input_b();
changes = last_b ^ current;
last_b = current;
//To handle key press event
if (bit_test(changes, 4) && !bit_test(last_b, 4))
{
row = 0; // zero based indexing
if (siCol1)
{
column = 0;
}
else if (siCol2)
{
column = 1;
}
else if (siCol3)
{
column = 2;
}
else if (siCol4)
{
column = 3;
}
}
else if (bit_test(changes, 5) && !bit_test(last_b, 5))
{
row = 1;
if (siCol1)
{
column = 0;
}
else if (siCol2)
{
column = 1;
}
else if (siCol3)
{
column = 2;
}
else if (siCol4)
{
column = 3;
}
}
else if (bit_test(changes, 6) && !bit_test(last_b, 6))
{
row = 2;
if (siCol1)
{
column = 0;
}
else if (siCol2)
{
column = 1;
}
else if (siCol3)
{
column = 2;
}
else if (siCol4)
{
column = 3;
}
}
else if (bit_test(changes, 7) && !bit_test(last_b, 7))
{
row = 3;
if (siCol1)
{
column = 0;
}
else if (siCol2)
{
column = 1;
}
else if (siCol3)
{
column = 2;
}
else if (siCol4)
{
column = 3;
}
}
return bKeyArrangement[row][column];
}
void KeyPadController( void )
{
//Check whether any key event occurs
if( bKeyPressed )
{
// 0-9
if (48 <= bPressedKey && 57 >= bPressedKey)
{
//Call a function to put the value of the key to a buffer
//for display and increment index of the buffer by 1
}
//Set the value to 0 so that the condition become false
bKeyPressed = 0;
//Check whether the condition becomes true more than once
printf("%c\r\n", bPressedKey); //Its getting called more than once
}
ScanColumn();
}
void ScanColumn( void )
{
siCol1 = 1;
siCol2 = 0;
siCol3 = 0;
siCol4 = 0;
output_bit(PIN_B0, 0);
output_bit(PIN_B1, 1);
output_bit(PIN_B2, 1);
output_bit(PIN_B3, 1);
delay_ms(10);
siCol1 = 0;
siCol2 = 1;
siCol3 = 0;
siCol4 = 0;
output_bit(PIN_B0, 1);
output_bit(PIN_B1, 0);
output_bit(PIN_B2, 1);
output_bit(PIN_B3, 1);
delay_ms(10);
siCol1 = 0;
siCol2 = 0;
siCol3 = 1;
siCol4 = 0;
output_bit(PIN_B0, 1);
output_bit(PIN_B1, 1);
output_bit(PIN_B2, 0);
output_bit(PIN_B3, 1);
delay_ms(10);
siCol1 = 0;
siCol2 = 0;
siCol3 = 0;
siCol4 = 1;
output_bit(PIN_B0, 1);
output_bit(PIN_B1, 1);
output_bit(PIN_B2, 1);
output_bit(PIN_B3, 0);
delay_ms(10);
}
//Interrupt mechanism
#int_RB
void RB_isr (void)
{
//global variable detecting key events
bKeyPressed = 1;
//Get the exact pressed
bPressedKey = GetPressedKey();
}
//Main function
void main(void)
{
set_tris_b(0xF0);
delay_us(10); //ensure line has time to settle
IOCB = 0xF0;
last_b = input_b();
delay_us(10); //ensure line has time to settle
//enabling interrupts on B port
clear_interrupt(INT_RB);
enable_interrupts(INT_RB);
enable_interrupts(GLOBAL)
while (1)
{
KeyPadController();
//Display the data on the 7 segments
DisplayData();
}
} |
My problem is that when I press any keys from the keypad the interrupt is getting called more than once and even unpredictable times. If I am not wrong then this is happening due to debouncing factor.
What should I do so that no interrupt is invoked when I press down the key. I need the interrupt only in the key up action and no key down is required.
PCH complier,
PIC18F452 micro-controller
MPLAB IDE 8.33 _________________ Bidesh Mukherjee
Software Engineer
Kolkata |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Dec 16, 2009 12:56 pm |
|
|
Quote: | #include <18F452.h>
IOCB = 0xF0;
My problem is that when I press any keys
|
The 18F452 does not have an IOCB register. Also, your program does not compile. Therefore, you are not really testing this code. |
|
|
Guest
|
Re: Handle port B interrupt and show data on 7segments LED |
Posted: Thu Dec 17, 2009 12:40 am |
|
|
Hi All,
I am trying to handle port B interrupt which is written for 4*4 matrix keypad and simultaneously display enter value on 12 seven segments LED.
I used the B0 to B3 port pin for column and B4 to B7 for row. Please look at the below code.
Code: |
//Device file
#include <18F452.h>
#fuses HS, NOWDT, NOLVP, NOBROWNOUT, NOPROTECT, PUT
#use delay(clock=4000000)
#use RS232 (baud=9600, parity=N, bits=8, xmit=PIN_C6, rcv=PIN_C7, errors, stream=RS232)
byte last_b;
byte row;
byte column;
short int siCol1, siCol2, siCol3, siCol4;
int8 bKeyPressed = 0;
BYTE bPressedKey;
BYTE bKeyArrangement [4][3] = {'1', '2', '3',
'4', '5', '6',
'7', '8', '9',
'R', '0', 'O'};
//Functions prototypes
void KeyPadController( void );
BYTE GetPressedKey( void );
void ScanColumn();
BYTE GetPressedKey( void )
{
byte changes;
int8 current;
current = input_b();
changes = last_b ^ current;
last_b = current;
//To handle key press event
if (bit_test(changes, 4) && !bit_test(last_b, 4))
{
row = 0; // zero based indexing
if (siCol1)
{
column = 0;
}
else if (siCol2)
{
column = 1;
}
else if (siCol3)
{
column = 2;
}
else if (siCol4)
{
column = 3;
}
}
else if (bit_test(changes, 5) && !bit_test(last_b, 5))
{
row = 1;
if (siCol1)
{
column = 0;
}
else if (siCol2)
{
column = 1;
}
else if (siCol3)
{
column = 2;
}
else if (siCol4)
{
column = 3;
}
}
else if (bit_test(changes, 6) && !bit_test(last_b, 6))
{
row = 2;
if (siCol1)
{
column = 0;
}
else if (siCol2)
{
column = 1;
}
else if (siCol3)
{
column = 2;
}
else if (siCol4)
{
column = 3;
}
}
else if (bit_test(changes, 7) && !bit_test(last_b, 7))
{
row = 3;
if (siCol1)
{
column = 0;
}
else if (siCol2)
{
column = 1;
}
else if (siCol3)
{
column = 2;
}
else if (siCol4)
{
column = 3;
}
}
return bKeyArrangement[row][column];
}
void KeyPadController( void )
{
//Check whether any key event occurs
if( bKeyPressed )
{
// 0-9
if (48 <= bPressedKey && 57 >= bPressedKey)
{
//Call a function to put the value of the key to a buffer
//for display and increment index of the buffer by 1
}
//Set the value to 0 so that the condition become false
bKeyPressed = 0;
//Check whether the condition becomes true more than once
printf("%c\r\n", bPressedKey); //Its getting called more than once
}
ScanColumn();
}
void ScanColumn( void )
{
siCol1 = 1;
siCol2 = 0;
siCol3 = 0;
siCol4 = 0;
output_bit(PIN_B0, 0);
output_bit(PIN_B1, 1);
output_bit(PIN_B2, 1);
output_bit(PIN_B3, 1);
delay_ms(10);
siCol1 = 0;
siCol2 = 1;
siCol3 = 0;
siCol4 = 0;
output_bit(PIN_B0, 1);
output_bit(PIN_B1, 0);
output_bit(PIN_B2, 1);
output_bit(PIN_B3, 1);
delay_ms(10);
siCol1 = 0;
siCol2 = 0;
siCol3 = 1;
siCol4 = 0;
output_bit(PIN_B0, 1);
output_bit(PIN_B1, 1);
output_bit(PIN_B2, 0);
output_bit(PIN_B3, 1);
delay_ms(10);
siCol1 = 0;
siCol2 = 0;
siCol3 = 0;
siCol4 = 1;
output_bit(PIN_B0, 1);
output_bit(PIN_B1, 1);
output_bit(PIN_B2, 1);
output_bit(PIN_B3, 0);
delay_ms(10);
}
//Interrupt mechanism
#int_RB
void RB_isr (void)
{
//global variable detecting key events
bKeyPressed = 1;
//Get the exact pressed
bPressedKey = GetPressedKey();
}
//Main function
void main(void)
{
set_tris_b(0xF0);
delay_us(10); //ensure line has time to settle
last_b = input_b();
delay_us(10); //ensure line has time to settle
//enabling interrupts on B port
clear_interrupt(INT_RB);
enable_interrupts(INT_RB);
enable_interrupts(GLOBAL);
while (1)
{
KeyPadController();
//Display the data on the 7 segments
//DisplayData();
}
} |
My problem is that when I press any keys from the keypad the interrupt is getting called more than once and even unpredictable times. If I am not wrong then this is happening due to debouncing factor.
What should I do so that no interrupt is invoked when I press down the key. I need the interrupt only in the key up action and no key down is required.
Please note that I have commented out the DisplayData method and statement IOCB = 0xF0. I have modified the code so that the code can be compiled.
PCH complier,
PIC18F452 micro-controller
MPLAB IDE 8.33 |
|
|
bideshm
Joined: 03 Dec 2007 Posts: 9 Location: India
|
Re: Handle port B interrupt and show data on 7segments LED |
Posted: Thu Dec 17, 2009 12:43 am |
|
|
Hi All,
Please pardon me as I have the modified the code as a guest member since I was unable to log in to the site.
Thanks, _________________ Bidesh Mukherjee
Software Engineer
Kolkata |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Dec 17, 2009 2:41 pm |
|
|
I think it would be a lot easier to do this if you modified the CCS keypad
routines, so they just poll the keypad in a timer interrupt. Set the
timer to interrupt at some suitable rate, such as every 10 ms.
This thread provides some hints:
http://www.ccsinfo.com/forum/viewtopic.php?t=40557
Also, I remembered that Newguy has posted some interrupt-driven
keypad code in the Code Library forum. I haven't tested this.
http://www.ccsinfo.com/forum/viewtopic.php?t=19726 |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|