|
|
View previous topic :: View next topic |
Author |
Message |
swapnil14327
Joined: 25 Jul 2014 Posts: 11
|
pic16f877a interfacing 4x7 matrix using switchs in KBD.C |
Posted: Wed Dec 10, 2014 2:03 pm |
|
|
Hello,
I am using generic code KBD.c
the above code uses single Port with 3 column and 4 rows
Code: |
#byte kbd = getenv("SFR:PORTD")
#define set_tris_kbd(x) set_tris_d(x)
#define COL0 (1 << 5)
#define COL1 (1 << 6)
#define COL2 (1 << 7)
#define ROW0 (1 << 1)
#define ROW1 (1 << 2)
#define ROW2 (1 << 3)
#define ROW3 (1 << 4) |
and provides 4x3 matrix.
Code: |
char const KEYS[4][3] = {{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}}; |
but i want 7x4 matrix.
i.e 4 Rows and 7 columns.
which will require 2 Ports. (consider Port A and B)
Port A -> Column.(pins 0,1,2,3,4,5,6)
Port B -> Row.(pins 0,1,2,3)
Code: |
char const KEYS[4][7] = {{'A','B','C','D','E','F','G'},
{'H','I','J','K','L','M','N'},
{'O','P','Q','R','S','T','U'},
{'V','W','X','Y','Z','1','2'}}; |
can any one help me modify the below function to get the exact value from the matrix of 4x7
Code: |
#define COL0 (1 << 5)
#define COL1 (1 << 6)
#define COL2 (1 << 7)
#define ROW0 (1 << 1)
#define ROW1 (1 << 2)
#define ROW2 (1 << 3)
#define ROW3 (1 << 4)
#define ALL_ROWS (ROW0|ROW1|ROW2|ROW3)
#define ALL_PINS (ALL_ROWS|COL0|COL1|COL2)
// Keypad layout:
char const KEYS[4][3] = {{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}};
#define KBD_DEBOUNCE_FACTOR 33 // Set this number to apx n/333 where
// n is the number of times you expect
// to call kbd_getc each second
int16 kbd_getc( ) {
static BYTE kbd_call_count;
static int1 kbd_down;
static int16 last_key;
static BYTE col;
BYTE kchar;
BYTE row;
kchar='\0';
if(++kbd_call_count>KBD_DEBOUNCE_FACTOR) {
switch (col) {
case 0 : set_tris_kbd(ALL_PINS&~COL0);
kbd=~COL0&ALL_PINS;
break;
case 1 : set_tris_kbd(ALL_PINS&~COL1);
kbd=~COL1&ALL_PINS;
break;
case 2 : set_tris_kbd(ALL_PINS&~COL2);
kbd=~COL2&ALL_PINS;
break;
}
if(kbd_down) {
if((kbd & (ALL_ROWS))==(ALL_ROWS)) {
kbd_down=FALSE;
kchar=last_key;
last_key='\0';
}
} else {
if((kbd & (ALL_ROWS))!=(ALL_ROWS)) {
if((kbd & ROW0)==0)
row=0;
else if((kbd & ROW1)==0)
row=1;
else if((kbd & ROW2)==0)
row=2;
else if((kbd & ROW3)==0)
row=3;
last_key =KEYS[row][col];
kbd_down = TRUE;
} else {
++col;
if(col==3)
col=0;
}
}
kbd_call_count=0;
}
set_tris_kbd(ALL_PINS);
return(kchar);
}
|
for reference i have attached the original code of KBD.c
Code: |
///////////////////////////////////////////////////////////////////////////
//// KBD.C ////
//// Generic keypad scan driver ////
|
++++++++++++++++++++++++
kbd.c removed. Reason: Forum rule #10
10. Don't post the CCS example code or drivers
http://www.ccsinfo.com/forum/viewtopic.php?t=26245
- Forum Moderator
++++++++++++++++++++++++
please suggest me some solution so that i can adjust the rows and columns. and enable them accordingly to get the exact value from matrix..
Thank You.. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Dec 10, 2014 3:17 pm |
|
|
Quote: | but i want 7x4 matrix.
i.e 4 Rows and 7 columns.
which will require 2 Ports. (consider Port A and B)
|
Here is a modified version of kbd.c, where I put the rows and columns
on separate ports. I think this code could easily be modified to do
what you need:
http://www.ccsinfo.com/forum/viewtopic.php?t=23467
Also, make sure you have pullup resistors (or the internal PIC pullups
enabled) on the row pins (not the column pins as the CCS file says).
The CCS driver reads the rows and strobes the columns low, one at
a time. Any key that is pressed will connect the low strobe (pulse) to
the row pin, where it will be read. The other row pins must be in a
defined logic state (not floating), therefore they must have pullups on
them. If the row pins are on Port B, you could turn on the internal pullups.
But there is a problem here:
Quote: |
Port A -> Column.(pins 0,1,2,3,4,5,6)
Port B -> Row.(pins 0,1,2,3)
|
The 16F877A only has 6 pins on PortA (A0 to A5). You need 7 pins for
the columns. Can you put the columns on Port D ? Then it would work. |
|
|
swapnil14327
Joined: 25 Jul 2014 Posts: 11
|
|
Posted: Thu Dec 11, 2014 12:14 am |
|
|
PCM programmer wrote: | Quote: | but i want 7x4 matrix.
i.e 4 Rows and 7 columns.
which will require 2 Ports. (consider Port A and B)
|
Here is a modified version of kbd.c, where I put the rows and columns
on separate ports. I think this code could easily be modified to do
what you need:
http://www.ccsinfo.com/forum/viewtopic.php?t=23467
Also, make sure you have pullup resistors (or the internal PIC pullups
enabled) on the row pins (not the column pins as the CCS file says).
The CCS driver reads the rows and strobes the columns low, one at
a time. Any key that is pressed will connect the low strobe (pulse) to
the row pin, where it will be read. The other row pins must be in a
defined logic state (not floating), therefore they must have pullups on
them. If the row pins are on Port B, you could turn on the internal pullups.
But there is a problem here:
Quote: |
Port A -> Column.(pins 0,1,2,3,4,5,6)
Port B -> Row.(pins 0,1,2,3)
|
The 16F877A only has 6 pins on PortA (A0 to A5). You need 7 pins for
the columns. Can you put the columns on Port D ? Then it would work. |
thanks mate..
I will try out asap..
also I have one question..
I am driving 28 LED using this technique..
1) Will LED will work in Matrix formation.?
2) I will have to connect each LED to a separate pin of PIC.?
if 2 case then i might need bigger pic with more pins on it..
my main motive is:
Once I press and hold "Switch 1" "LED 1" will be ON. Release switch LED OFF.
MOTIVE::
1)"Switch 1" pressed and hold. "LED 1" ON.
2)Considering "Switch 1" is pressed, I press and hold "Switch 2" "LED 1" should be "OFF" and "LED 2" should be ON
3)Switch 1(pressed) - - LED 1(ON)
Switch 1(pressed)Switch 2(pressed) - - LED 1(OFF) LED 2(ON)
Switch 1(pressed)Switch 2(pressed)Switch 3(pressed) - - LED 1(OFF) LED 2(OFF)LED 3(ON)
and so on when all Switches pressed(Serially 1 to 28) only LED 28 will be ON
will the above concept work with the code ? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19500
|
|
Posted: Thu Dec 11, 2014 1:36 am |
|
|
LED multiplexing.
Perfectly standard. Just about every display you see with more than a handful of LED's, will be multiplex driven.
But. Remember that each LED will only be 'on' for 1/nth the time. If you have an 8 column LED matrix, each column is only on for 1/8th the time. If you want the LED's to look as bright as when they are driven directly, and you use (perhaps) 10mA for direct drive, then you will need to deliver 80mA for the 1/8th the time the LED is 'on', to make the multiplexed display look as bright. Beyond the capabilities of a PIC pin, without transistors or similar buffers. Then remember that the switching will need to be regular and fast. The whole display must be refreshed perhaps at least 100* per second.
As a comment on the switches, you could drive the matrix as (say) 7*4, and then use a 3-8line decoder to drive the rows. Total of 7 pins, to drive the entire keyboard. |
|
|
swapnil14327
Joined: 25 Jul 2014 Posts: 11
|
4x7 keypad with pic16f946 |
Posted: Thu Dec 11, 2014 2:21 pm |
|
|
hello can any one help me with the below code..
its not working..
as pic16f877a was not sufficient with IO.
i am using pic16f946.
kbd.c
Code: | #byte kbd_rows = 0x189 // Port g
#byte kbd_cols = 0x188 // Port f
#define set_tris_kbd_rows(x) set_tris_g(x)
#define set_tris_kbd_cols(x) set_tris_f(x)
#define Bitmask(x) (1 << (x & 7))
#define COL0 Bitmask(PIN_F0)
#define COL1 Bitmask(PIN_F1)
#define COL2 Bitmask(PIN_F2)
#define COL3 Bitmask(PIN_F3)
#define COL4 Bitmask(PIN_F4)
#define COL5 Bitmask(PIN_F5)
#define COL6 Bitmask(PIN_F6)
#define ROW0 Bitmask(PIN_G0)
#define ROW1 Bitmask(PIN_G1)
#define ROW2 Bitmask(PIN_G2)
#define ROW3 Bitmask(PIN_G3)
#define ALL_ROWS (ROW0|ROW1|ROW2|ROW3)
#define ALL_PINS (ALL_ROWS|COL0|COL1|COL2|COL3|COL4|COL5|COL6)
// Keypad layout:
char const KEYS[4][3] = {{'A','B','C','D','E','F','G'},
{'H','I','J','K','L','M','N'},
{'O','P','Q','R','S','T','U'},
{'V','W','X','Y','Z','1','2'}};
#define KBD_DEBOUNCE_FACTOR 333 // Set this number to apx n/333 where
// n is the number of times you expect
// to call kbd_getc each second
void kbd_init() {
}
int16 kbd_getc( ) {
static BYTE kbd_call_count;
static int1 kbd_down;
static int16 last_key;
static BYTE col;
BYTE kchar;
BYTE row;
kchar='\0';
if(++kbd_call_count>KBD_DEBOUNCE_FACTOR) {
switch (col) {
case 0 : set_tris_kbd(ALL_PINS&~COL0);
kbd=~COL0&ALL_PINS;
break;
case 1 : set_tris_kbd(ALL_PINS&~COL1);
kbd=~COL1&ALL_PINS;
break;
case 2 : set_tris_kbd(ALL_PINS&~COL2);
kbd=~COL2&ALL_PINS;
break;
case 3 : set_tris_kbd(ALL_PINS&~COL3);
kbd=~COL3&ALL_PINS;
break;
case 4 : set_tris_kbd(ALL_PINS&~COL4);
kbd=~COL4&ALL_PINS;
break;
case 5 : set_tris_kbd(ALL_PINS&~COL5);
kbd=~COL5&ALL_PINS;
break;
case 6 : set_tris_kbd(ALL_PINS&~COL6);
kbd=~COL6&ALL_PINS;
break;
}
if(kbd_down) {
if((kbd & (ALL_ROWS))==(ALL_ROWS)) {
kbd_down=FALSE;
kchar=last_key;
last_key='\0';
}
} else {
if((kbd & (ALL_ROWS))!=(ALL_ROWS)) {
if((kbd & ROW0)==0)
row=0;
else if((kbd & ROW1)==0)
row=1;
else if((kbd & ROW2)==0)
row=2;
else if((kbd & ROW3)==0)
row=3;
last_key =KEYS[row][col];
kbd_down = TRUE;
} else {
++col;
if(col==3)
col=0;
}
}
kbd_call_count=0;
}
set_tris_kbd(ALL_PINS);
return(kchar);
} |
main code:
Code: |
#include <kbd.c>
void main()
{
char k,s;
int i=0; //counter
kbd_init();
while (TRUE)
{
k=kbd_getc();
switch(k)
{
case 'A':
output_high(PIN_A0);
break;
case 'B' :
output_high(PIN_A1);
break;
}
}
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Dec 11, 2014 2:49 pm |
|
|
You changed a whole bunch of stuff from my example code in the link.
In my example code for 2 ports, I've got this:
Code: | #define ALL_ROWS (ROW0|ROW1|ROW2|ROW3)
#define ALL_COLS (COL0|COL1|COL2)
|
For some reason, you changed it to this:
Quote: | #define ALL_ROWS (ROW0|ROW1|ROW2|ROW3)
#define ALL_PINS (ALL_ROWS|COL0|COL1|COL2|COL3|COL4|COL5|COL6) |
How is the ALL_PINS thing going to work ? The rows and columns are
on different i/o ports. The CCS functions only work on one port at a time !
Then you changed this. I would just leave it at the default 33 for now.
Quote: | #define KBD_DEBOUNCE_FACTOR 333 // Set this number to apx n/333 |
Next, you've got the switch-case statement where you're loading 'kbd'
with the column strobe bitmask. But there is no 'kbd' variable in the
2 port code in the link that I gave you. Also you're putting in ALL_PINS
and as I explained, you can't set tris on two ports at a time with the
CCS functions.
Quote: | if(++kbd_call_count>KBD_DEBOUNCE_FACTOR) {
switch (col) {
case 0 : set_tris_kbd(ALL_PINS&~COL0);
kbd=~COL0&ALL_PINS;
break;
case 1 : set_tris_kbd(ALL_PINS&~COL1);
kbd=~COL1&ALL_PINS;
break; |
In my link, I use kbd_cols, as shown below:
Code: | if(++kbd_call_count>KBD_DEBOUNCE_FACTOR) {
switch (col) {
case 0 : set_tris_kbd_cols(ALL_COLS&~COL0);
kbd_cols=~COL0&ALL_COLS;
break;
case 1 : set_tris_kbd_cols(ALL_COLS&~COL1);
kbd_cols=~COL1&ALL_COLS;
break;
|
Basically you need to copy what I'm doing in the example that I gave
you and not invent stuff.
Last edited by PCM programmer on Thu Dec 11, 2014 2:54 pm; edited 1 time in total |
|
|
swapnil14327
Joined: 25 Jul 2014 Posts: 11
|
|
Posted: Thu Dec 11, 2014 2:53 pm |
|
|
i want to use 4x7 keypad
so i have to use two ports.. one for rows and other for coulum..
the example you gave is for 4x3 keypad..(12 switches)
i tried the modification but its not working..
can you suggest me some design for 4x7 keypad..(28 switches) |
|
|
swapnil14327
Joined: 25 Jul 2014 Posts: 11
|
|
Posted: Thu Dec 11, 2014 2:56 pm |
|
|
how do i upload an image in here..?
i have the design but not able to upload the photo.. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Dec 11, 2014 3:43 pm |
|
|
Quote: | i want to use 4x7 keypad
so i have to use two ports.. one for rows and other for coulum..
the example you gave is for 4x3 keypad..(12 switches)
i tried the modification but its not working..
|
I gave you some of the reasons why it's not working. The code is easily
expandable to a 4x7 keypad. I don't think I can do much more on this
thread.
Quote: | how do i upload an image in here..? |
Use http://www.postimage.com or http://www.imageshack.com
or some other free image hosting service.
Upload your schematic to that website. Preferably a .JPG file or some
other commonly used image format.
Then post a link to your image here in the forum. Use the Preview
button to view your post and see if the link is working correctly, before
you press the Submit button. |
|
|
swapnil14327
Joined: 25 Jul 2014 Posts: 11
|
|
Posted: Thu Dec 11, 2014 5:17 pm |
|
|
Thanks again mate...
works fine now changed completely according to your code..
just some glitches....
working with them now..
Code: |
#byte kbd_rows = 0x189 // Port g
#byte kbd_cols = 0x188 // Port f
#define set_tris_kbd_rows(x) set_tris_g(x)
#define set_tris_kbd_cols(x) set_tris_f(x)
#define Bitmask(x) (1 << (x & 7))
//Keypad connection: (for example column 0 is B2)
#define COL0 Bitmask(PIN_F0)
#define COL1 Bitmask(PIN_F1)
#define COL2 Bitmask(PIN_F2)
#define COL3 Bitmask(PIN_F3)
#define COL4 Bitmask(PIN_F4)
#define COL5 Bitmask(PIN_F5)
#define COL6 Bitmask(PIN_F6)
#define ROW0 Bitmask(PIN_G0)
#define ROW1 Bitmask(PIN_G1)
#define ROW2 Bitmask(PIN_G2)
#define ROW3 Bitmask(PIN_G3)
#define ALL_ROWS (ROW0|ROW1|ROW2|ROW3)
#define ALL_COLS (COL0|COL1|COL2|COL3|COL4|COL5|COL6)
// Keypad layout:
char const KEYS[4][7] = {{'A','B','C','D','E','F','G'},
{'H','I','J','K','L','M','N'},
{'O','P','Q','R','S','T','U'},
{'V','W','X','Y','Z','1','2'}};
#define KBD_DEBOUNCE_FACTOR 33 // Set this number to apx n/333 where
// n is the number of times you expect
// to call kbd_getc each second
void kbd_init() {
}
int16 kbd_getc( ) {
static BYTE kbd_call_count;
static int1 kbd_down;
static int16 last_key;
static BYTE col;
BYTE kchar;
BYTE row;
kchar='\0';
if(++kbd_call_count>KBD_DEBOUNCE_FACTOR) {
switch (col) {
case 0 : set_tris_kbd_cols(ALL_COLS&~COL0);
kbd_cols=~COL0&ALL_COLS;
break;
case 1 : set_tris_kbd_cols(ALL_COLS&~COL1);
kbd_cols=~COL1&ALL_COLS;
break;
case 2 : set_tris_kbd_cols(ALL_COLS&~COL2);
kbd_cols=~COL2&ALL_COLS;
break;
case 3 : set_tris_kbd_cols(ALL_COLS&~COL3);
kbd_cols=~COL3&ALL_COLS;
break;
case 4 : set_tris_kbd_cols(ALL_COLS&~COL4);
kbd_cols=~COL4&ALL_COLS;
break;
case 5 : set_tris_kbd_cols(ALL_COLS&~COL5);
kbd_cols=~COL5&ALL_COLS;
break;
case 6 : set_tris_kbd_cols(ALL_COLS&~COL6);
kbd_cols=~COL6&ALL_COLS;
break;
}
if(kbd_down) {
if((kbd_rows & (ALL_ROWS))==(ALL_ROWS)) {
kbd_down=FALSE;
kchar=last_key;
last_key='\0';
}
} else {
if((kbd_rows & (ALL_ROWS))!=(ALL_ROWS)) {
if((kbd_rows & ROW0)==0)
row=0;
else if((kbd_rows & ROW1)==0)
row=1;
else if((kbd_rows & ROW2)==0)
row=2;
else if((kbd_rows & ROW3)==0)
row=3;
last_key =KEYS[row][col];
kbd_down = TRUE;
} else {
++col;
if(col==3)
col=0;
}
}
kbd_call_count=0;
}
set_tris_kbd_rows(ALL_ROWS);
set_tris_kbd_cols(ALL_COLS);
return(kchar);
}
|
now this happens.:
Switch 1 ON -> Led 1 ON.
Switch 1 and 2 ON -> Led 1 and 2 ON..
i want only led 2 to be ON in second case and Led 1 OFF..
how can i reset the earlier LED before making next LED ON.
I am using output_high(pin) / output_low(pin) function.. is there any other way to do this.. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Thu Dec 11, 2014 5:25 pm |
|
|
You'll have to post your 'LED control' portion of code to get a reply !! Without seeing that,we can't make a proper assessment of what you're doing and how to correct it.
Jay |
|
|
swapnil14327
Joined: 25 Jul 2014 Posts: 11
|
|
Posted: Thu Dec 11, 2014 5:35 pm |
|
|
Code: |
#include "kbd.c"
void main()
{
char k,s;
int i=0; //counter
kbd_init();
while (TRUE)
{
k = kbd_getc();
if(k != 0)
if(k=='A')
{
output_high(PIN_A0);
}
elseif(k=='B')
{
output_low(PIN_A0);
output_high(PIN_A1);
}
elseif(k=='C')
{
output_low(PIN_A1);
output_high(PIN_A2);
}
}
}
|
I have also used If-else.. but still i have to do it manually every time(reseting previous LED before next led to be ON).. |
|
|
|
|
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
|