CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

4x4 keypad trouble!

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Tuned
Guest







4x4 keypad trouble!
PostPosted: Sat Nov 20, 2004 10:03 am     Reply with quote

Hi, i am trying to use a LCD with a generic 4x4 keypad on a pic 16f876 at 4Mhz. The LCD works, but inthe ccs example code ex_lcdkb, the keypad, doesn�t. The LCD is in port D and the keypad on port B. I�ve found the code below for keypad interfacing, but it does�t work, also I�ve tried to modify kbd.c to work with a 4x4 keypad unsuccesfully.

This is the code:
Code:

#byte kbd = 0xF81 // This puts the entire structure


#define set_tris_kbd(x) set_tris_b(x)



//Keypad connection: (for example column 0 is B2)
// Bx:


#define COL0 (1 << 0) //1
#define COL1 (1 << 1) //10
#define COL2 (1 << 2) //100
#define COL3 (1 << 3) //1000

#define ROW0 (1 << 4) //10000
#define ROW1 (1 << 5) //100000
#define ROW2 (1 << 6) //1000000
#define ROW3 (1 << 7) //10000000

// The following bitmasks are the same as the above,

// but written in a different format.




#define ALL_ROWS (ROW0|ROW1|ROW2|ROW3)
#define ALL_PINS (ALL_ROWS|COL0|COL1|COL2|COL3)

// Keypad layout:
char const KEYS[4][4] = {{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}};

#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() {
   //port_b_pullups(false);
}

char kbd_getc() {
   static BYTE kbd_call_count;
   static short int kbd_down;
   static char 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;
               }

      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==4)
               col=0;
         }
      }
      kbd_call_count=0;
      }
   set_tris_kbd(ALL_PINS);
   return(kchar);
}

If anyone could help me y would apreciate it. Thanks.
J_Purbrick



Joined: 16 Sep 2003
Posts: 9

View user's profile Send private message

PostPosted: Sat Nov 20, 2004 10:56 am     Reply with quote

Here's a routine that I wrote for a PIC16F877. In this case I didn't want the ASCII values of the pushbuttons, but 0, 1, 2 etc for the numeric ones, 0xA, 0xB etc for the letters ABCD and 0xE for *, 0xF for #. The arrangement of the buttons is

1 2 3 A
4 5 6 B
7 8 9 C
* 0 # D

The rows (top-bottom) are on bits 4-7, and the columns (right to left, I forget why) should have been on bits 0-3, but the processor was programmed usiing the 5 volt method, which means that bit 3 of port B isn't usable, so bit 2 of port A is used instead. It should be easy to see how to make it work entirely with port B. The code could be more efficient, but it works. You need to enable the weak pullups for port B.

Code:

            // For remapping pushbuttons
int const remap[16] = {1, 2, 3, 0xA, 4, 5, 6, 0xB, 7, 8, 9, 0xC, 0xE, 0, 0xF, 0xD};

int read_keypad(void)
{
   int d, button;

   portb = 0;

   bit_clear(trisb, 0);
   d = portb & 0xF0;                        // Top 4 bits of port B
   bit_set(trisb, 0);
   if (d != 0xF0)                              // ABCD pressed   
      d = d + 1;

   else                                 // Not ABCD
   {
      bit_clear(trisb, 1);
      d = portb & 0xF0;                        // Top 4 bits of port B
      bit_set(trisb, 1);
      if (d != 0xF0)                              // 369# pressed   
         d = d+2;

      else                                 // Not 369#
      {
         bit_clear(trisb, 2);
         d = portb & 0xF0;                        // Top 4 bits of port B
         bit_set(trisb, 2);
         if (d != 0xF0)                              // 2580 pressed   
            d = d + 3;
         else                                 // Not 2580
         {
            bit_clear(trisa, 2);
            bit_clear(porta, 2);
            d = portb & 0xF0;                        // Top 4 bits of port B
            bit_set(trisa, 2);
         }
      }
   }

   button = 0xFF;
   if (!bit_test(d,4))
      button = 0;                                 // Top row
   else if (!bit_test(d,5))
      button = 4;                                 // 2nd row
   else if (!bit_test(d,6))
      button = 8;                                 // 3rd row
   else if (!bit_test(d,7))
      button = 12;                              // Bottom row

   if (button != 0xFF)                        // Anything pressed?
   {
      button += (d & 3);
      button = remap[button];
   }
   return(button);
}

PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Nov 20, 2004 11:19 am     Reply with quote

Just a couple things -- I didn't check your entire program but:

The following line is for an 18F PIC. The CCS example file has
some conditional statements at the start of the file. You've removed
the line that is needed for your 16F PIC and left in the 18F line.
The address of Port B in a 16F PIC is 0x06. You need to fix this.
Quote:
#byte kbd = 0xF81


The 2nd thing is that pull-ups are required for the keypad.
You need to un-comment the statement that enables port B pullups.
Tuned
Guest







PostPosted: Sat Nov 20, 2004 11:25 am     Reply with quote

Thanks for your help, but in this case I need the ascii values of the buttons.Also what I need is to adapt the kbd.c routine to work with an 4x4 keypad on port B, something like the code I posted.

Thanks again, it�s nice to see there�s people who still help each other.
Tuned
Guest







PostPosted: Sat Nov 20, 2004 11:37 am     Reply with quote

Yes, the problem was #byte kbd=0xF81, that was for 18f MCUs. As soon as I changed that, the program started to work.

Thanks to all!
buckeyes1997
Guest







what is correct
PostPosted: Mon Nov 22, 2004 9:29 am     Reply with quote

what did you change the f81 value to to make it work?
matt
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Mon Nov 22, 2004 10:30 am     Reply with quote

Read PCM's post

Quote:
The following line is for an 18F PIC. The CCS example file has
some conditional statements at the start of the file. You've removed
the line that is needed for your 16F PIC and left in the 18F line.
The address of Port B in a 16F PIC is 0x06. You need to fix this.
Quote:
#byte kbd = 0xF81


So the answer is 0x06
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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