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 support@ccsinfo.com

Keypad help.

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



Joined: 09 Aug 2005
Posts: 32

View user's profile Send private message

Keypad help.
PostPosted: Tue Jun 07, 2011 2:53 pm     Reply with quote

I try to use the keypad 4x3 (digikey P/N: GH5001-ND). I have the PIC Demo Z board and connect to the keypad to the PORTB, I also have a 7-segment on PORTD. Anytime the keypad pressed, I want to display the result on to the 7-segment.

I try to modify the kbd.c file that came with the compiler to use as driver. Does anyone have this driver works.

I know that my 7-segment function display_number(k);
works fine when I display the debug number, it displays ok.

Please help me. Thanks in advances.

here are my code:

main.c
Code:
//main.c
#include <prototype.h>

#include <kbd.c>

char temp = 5;   //debug only
char counter = 0;


//void display_number(char digit);
/* PROTOTYPE -- Display to 7-segment  */
void display_number(char digit)
{
   output_d(Digit_Map[digit]);            output_low(DIGIT1);            
   delay_ms(4);
   output_high(DIGIT1);
}


// main.c start here
main(void)
{
   char k;
   port_b_pullups(true);
   kbd_init();


   while(1)
   {
         
   //   counter = 2;      //debug only
//              display_number(counter);          // debug only
                                k = kbd_getc();
      display_number(k);
      delay_ms(10);
      
   
   }
}


prototype.h file

Code:
#include <18F4620.h>
#device ICD=TRUE //ADC=10
#fuses XT, NOLVP, NOWDT, NOXINST
#use delay (clock=4000000)
#use rs232 (baud=9600, xmit=PIN_C6, rcv=PIN_C7)


//===================================================
// This is for isi_7_segment only
/*
      output_high(PIN_D1);   //a
      output_high(PIN_D0);   //b
      output_high(PIN_D3);   //c
      output_high(PIN_D2);   //d
      output_high(PIN_D5);   //e
      output_high(PIN_D4);   //f
      output_high(PIN_D7);   //g
*/
//                            0    1    2    3    4    5    6    7    8    9     
const char Digit_Map[10] = {0x7F,0x49,0xE7,0xCF,0xD9,0xDE,0xFE,0x4B,0xFF,0xDF};

// Digits
#define DIGIT3  PIN_A3
#define DIGIT2  PIN_A4
#define DIGIT1  PIN_A5

//===============================================================

//PICDemo Z
#define   S2   PIN_B5
#define S3   PIN_B4
#define   D1   PIN_A0
#define D2   PIN_A1


kbd.c file
Code:
///////////////////////////////////////////////////////////////////////////
////                             KBDD.C                                ////
////                  Generic keypad scan driver                       ////
////                                                                   ////
////  kbd_init()   Must be called before any other function.           ////
////                                                                   ////
////  c = kbd_getc(c)  Will return a key value if pressed or /0 if not ////
////                   This function should be called frequently so as ////
////                   not to miss a key press.                        ////
////                                                                   ////
///////////////////////////////////////////////////////////////////////////
////        (C) Copyright 1996,2003 Custom Computer Services           ////
//// This source code may only be used by licensed users of the CCS C  ////
//// compiler.  This source code may only be distributed to other      ////
//// licensed users of the CCS C compiler.  No other use, reproduction ////
//// or distribution is permitted without written permission.          ////
//// Derivative programs created using this software in object code    ////
//// form are not restricted in any way.                               ////
///////////////////////////////////////////////////////////////////////////

////////////////// The following defines the keypad layout on port D

// Un-comment the following define to use port B
 #define use_portb_kbd TRUE

// Make sure the port used has pull-up resistors (or the LCD) on
// the column pins


#if defined(__PCH__)
#if defined use_portb_kbd
   #byte kbd = 0xF81                   // This puts the entire structure
#else
   #byte kbd = 0xF83                   // This puts the entire structure
#endif
#else
#if defined use_portb_kbd
   #byte kbd = 6                  // on to port B (at address 6)
#else
   #byte kbd = 8                 // on to port D (at address 8)
#endif
#endif

#if defined use_portb_kbd
   #define set_tris_kbd(x) set_tris_b(x)
#else
   #define set_tris_kbd(x) set_tris_d(x)
#endif



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

#ifdef blue_keypad  ///////////////////////////////////// For the blue keypad
#define COL0 (1 << 2)
#define COL1 (1 << 3)
#define COL2 (1 << 6)

#define ROW0 (1 << 4)
#define ROW1 (1 << 7)
#define ROW2 (1 << 1)
#define ROW3 (1 << 5)

#else ////////////////////////////////////////////////// For the black keypad
#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)

#endif

#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


void kbd_init() {
}

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;
       }

       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);
}
[/code]
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Jun 07, 2011 2:59 pm     Reply with quote

Quote:

#include <prototype.h>

#include <kbd.c>


See this post:
http://www.ccsinfo.com/forum/viewtopic.php?t=30842&start=1&highlight=use_portb_kbd
newpic



Joined: 09 Aug 2005
Posts: 32

View user's profile Send private message

keypad help
PostPosted: Tue Jun 07, 2011 10:19 pm     Reply with quote

I try that and it still does nothing. I try to debug and watch the char k in the watch window and it always display '0' no matter what number I pressed.

I noticed that kbd.c file, the kbd_init() does not show any statement at all and this is what it came with the compiler.

Help need.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Jun 07, 2011 10:40 pm     Reply with quote

Look at the while() loop in this CCS example file:
Quote:
c:\program files\picc\examples\ex_lcdkb.c

It shows how to call the kbd_getc() function. You must test the return
value to see if it's non-zero. If it's non-zero, then you can use it.
You need to write your code in the same way. Also, don't attempt to
step through the code in a debugger. Just run it.
newpic



Joined: 09 Aug 2005
Posts: 32

View user's profile Send private message

KEYPAD
PostPosted: Wed Jun 08, 2011 2:42 pm     Reply with quote

I still get nothing from k=kbd_getc().

I decide to change to flex_bcd.c as follow
Code:
//Keypad connection:

#define col0 PIN_B4
#define col1 PIN_B5
#define col2 PIN_B6
#define row0 PIN_B0
#define row1 PIN_B1
#define row2 PIN_B2
#define row3 PIN_B3

// 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



void kbd_init()
{
   port_b_pullups(true);
}


short int ALL_ROWS (void)
{
   if (input (row0) & input (row1) & input (row2) & input (row3))
      return (0);
   else
      return (1);
}



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   : output_low(col0);
                     output_high(col1);
                     output_high(col2);
                    break;
         case 1   : output_high(col0);
                     output_low(col1);
                     output_high(col2);
                    break;
         case 2   : output_high(col0);
                     output_high(col1);
                     output_low(col2);
                    break;
       }

       if(kbd_down) {
         if(!ALL_ROWS()) {
           kbd_down=false;
           kchar=last_key;
           last_key='\0';
         }
       } else {
          if(ALL_ROWS()) {
             if(!input (row0))
               row=0;
             else if(!input (row1))
               row=1;
             else if(!input (row2))
               row=2;
             else if(!input (row3))
               row=3;
             last_key =KEYS[row][col];
             kbd_down = true;
          } else {
             ++col;
             if(col==3)
               col=0;
          }
       }
      kbd_call_count=0;
   }
  return(kchar);


main.c
Code:
//main.c
#include <prototype.h>
#include <flex_kbd.c>

char temp = 245;   //debug only
char counter = 0;


//void display_number(char digit);
/* PROTOTYPE -- Display to 7-segment  */
void display_number(char digit)
{
   output_d(Digit_Map[digit]);         
   output_low(DIGIT1);   
   
   delay_ms(100);
   output_high(DIGIT1);

}


// main.c start here
main(void)
{
   char k;
   kbd_init();
   while(1)
   {
      k=kbd_getc();
      k=kbd_getc();
         if(k!=0)
           if(k=='*')
          display_number(0x7F);  //0x7F is 0 per my Digit_Map[]
         else
              display_number(k);
          delay_ms(10);
      
   
   }
}


if I pressed 1 on the keypad, I got on the 7-seg is junk (segment e,f,g lit up) it is not a 1. I have my keypad pin wire as follow
Quote:
1 ----B0
2----B1
3----B2
4----B3

5----B4
6----B5
7----B6


Any suggestion will be appreciate.
Ttelmah



Joined: 11 Mar 2010
Posts: 19402

View user's profile Send private message

PostPosted: Wed Jun 08, 2011 3:11 pm     Reply with quote

Hint:
Is the text character '1', the same as the number 1.....

Best Wishes
newpic



Joined: 09 Aug 2005
Posts: 32

View user's profile Send private message

PostPosted: Thu Jun 09, 2011 1:34 pm     Reply with quote

I guess they are different
I couldn't make the kbd.c driver to work,

I try to use
Code:

k = kbd_getc();
k=k-'0';                 %Subtract value of '0' to convert to number.
display_number(k);

but it makes no difference.

what else could it be?

so I mod. the main code and create kbd_driver.c as follow and it does display ok when the specific key pressed. It is more for debug because it will scans multiple times from the main loop. If this is a long program it will miss the key pressed.

Note: I also change keypad connection to different pins instead of portb so I can use B6 for debug and steping through the code.
main.c

Code:
//main.c
#include <prototype.h>
#include <kbd_driver.c>


//void display_number(char digit);
/* PROTOTYPE -- Display to 7-segment  */
void display_number(char digit)
{
   output_d(Digit_Map[digit]);         

   output_low(DIGIT2);

   delay_ms(1);

   output_high(DIGIT2);

}


// main.c start here
void main(void)
{
   char k;
   char last_k;


   while(1)
   {
      init();
      k = get_key1();
      k = get_key2();
      k = get_key3();
      last_k = k;
      display_number(k);
      
   }
}


kbd_driver.c
Code:
//Keypad connection:

#define col0 PIN_B0
#define col1 PIN_B1
#define col2 PIN_B2

#define row0 PIN_C2
#define row1 PIN_C1
#define row2 PIN_C0
#define row3 PIN_A2


void init()
{
//   port_b_pullups(true);
//   output_high(row0);
   output_c(0x00);
   set_tris_c(0xff);
}

char get_key1()
{
   char k;
   output_high(col0);   // scan column 0
   
   if(input(row0))
   {
      k = 1;

   }
   else if(input(row1))
   {
      k = 4;
   
   }
   else if(input(row2))
   {
      k = 7;
   }
   output_low(col0);   //  column 0 off
   return (k);
   
}

char get_key2()
{
   char k;
   output_high(col1);   // scan column 1
   
   if(input(row0))
   {
      k = 2;

   }
   else if(input(row1))
   {
      k = 5;
   
   }
   else if(input(row2))
   {
      k = 8;
   }
   
   output_low(col1);   //  column 1 off
   return (k);
   

}

//=========
char get_key3()
{
   char k;
   output_high(col2);   // scan column 2
   
   if(input(row0))
   {
      k = 3;

   }
   else if(input(row1))
   {
      k = 6;
   
   }
   else if(input(row2))
   {
      k = 9;
   }
   output_low(col2);   //  column 2 off
   return (k);
   

}


I still want to use the kbd.c to work but out of idea, I would appreciate if anyone can pin point to my problems.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jun 09, 2011 1:53 pm     Reply with quote

Quote:
GH5001

I still want to use the kbd.c to work but out of idea, I would appreciate if
anyone can pin point to my problems.

I have that keypad. What's your compiler version ?
newpic



Joined: 09 Aug 2005
Posts: 32

View user's profile Send private message

PostPosted: Thu Jun 09, 2011 2:42 pm     Reply with quote

I have
Code:
CCS PCH C Compiler, Version 3.207, 24657
MPLAB 8.60
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jun 09, 2011 3:25 pm     Reply with quote

I don't have the PCH compiler for vs. 3.207, but I do have the PCM
compiler for that version. So I made a test program for the 16F877 and it
works. It displays this on the TeraTerm window when I press each key:
Quote:

123456789*0#


This was tested on a PicDem2-Plus board (non-Rohs version) with the
GH5001 keypad, with your same connections. Here's the test program:
Code:

#include <16F877.H>
#fuses XT, NOWDT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

#define use_portb_kbd 1
#include <kbd.c>

//==========================================
void main()
{
int8 k;

port_b_pullups(TRUE);

kbd_init();

while(1)
  {
   k = kbd_getc();
   if(k!=0)
      putc(k);
  }

}


The closest version I have to 3.207 of PCH is vs. 3.230. That's not close
enough to be worth trying. Vs. 3.200 was a large revision point by CCS.
It's possible that 3.207 is buggy for your PIC. You could add the
NOPBADEN fuse, which will make sure that PortB comes up as digitial
i/o, instead of analog:
Quote:

#include <18F4620.h>
#device ICD=TRUE //ADC=10
#fuses XT, NOLVP, NOWDT, NOXINST,NOPBADEN
#use delay (clock=4000000)
#use rs232 (baud=9600, xmit=PIN_C6, rcv=PIN_C7)

Also, I would get rid of the #device ICD=TRUE and just run the code in
standalone mode. Don't try to debug it or step through the code. See
if it works.

If you have a 16F877, you could also try testing it with that PIC.
newpic



Joined: 09 Aug 2005
Posts: 32

View user's profile Send private message

PostPosted: Fri Jun 10, 2011 7:57 am     Reply with quote

I have
Quote:
CCS PCM C Compiler, Version 3.249, 34474

using PIC16F877 and Pic demo 2 plus (old version as you have)I cut and paste your test code above. I build it and program it into board.

I got the following when key pressed:
key pressed ---------- hyperterminal
1 ----------------------- 0 * #
2 ----------------------- nothing
3 ----------------------- nothing
4 ----------------------- nothing
5 ----------------------- 1
6 ----------------------- 2
7 ----------------------- nothing
8 ----------------------- 4
9 ----------------------- 5
* ----------------------- nothing
0 ----------------------- 7
# ---------------------- 8
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Jun 10, 2011 11:56 am     Reply with quote

Check your connections. Just by flipping around the connectors
and moving them "off" by 1 pin, I was able to get some strange effects.

The GH5001 data sheet shows the pin numbering system for the keypad.
Look on page 1, at the middle diagram (called Standard Versions). Look
at the pinout given at the bottom. That's the back side of the keypad.
http://media.digikey.com/pdf/Data%20Sheets/Grayhill%20PDFs/96%20Series.pdf
It looks like this:
Code:

   -------------------
   |  7 6 5 4 3 2 1  |
   |                 |
   |                 |
   |                 |
   |                 |
   |                 |
   |                 |
   |                 |
   |                 |
   |                 |
   |                 |
   |                 |
   -------------------


Connections between PIC and keypad:
Code:

   Keypad   PortB
     1.......B1
     2.......B2
     3.......B3
     4.......B4
     5.......B5
     6.......B6
     7.......B7

Note there is no connection to Pin B0 on PortB.
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