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 Problem Pic18fxxkxx

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
[email protected]



Joined: 22 Aug 2013
Posts: 22

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

4x4 Keypad Problem Pic18fxxkxx
PostPosted: Thu Aug 22, 2013 3:59 pm     Reply with quote

Hi, all I am new programmer in CCS,
I read CCS manual and also many topic about keypad,
I used PCM Programmer's code :
Code:

#include <18F452.h>
#fuses EC_IO,NOWDT,NOPROTECT,BROWNOUT,PUT,NOLVP
#use delay(clock=4000000) 
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

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

//Keypad connection:
#define row0 PIN_B4
#define row1 PIN_B5
#define row2 PIN_B6
#define row3 PIN_B7
#define col0 PIN_B0
#define col1 PIN_B1
#define col2 PIN_B2
#define col3 PIN_B3

// 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()
{
//set_tris_b(0xF0);
//output_b(0xF0);
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);
        output_high(col3);
        break;
   
      case 1:
        output_high(col0);
        output_low(col1);
        output_high(col2);
        output_high(col3);
        break;

      case 2:
        output_high(col0);
        output_high(col1);
        output_low(col2);
        output_high(col3);
        break;

      case 3:
        output_high(col0);
        output_high(col1);
        output_high(col2);
        output_low(col3);
        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==4)
            col=0;
        }
     }
   kbd_call_count=0;
  }
return(kchar);
}

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

kbd_init();

printf("\r\Starting ...");

while(TRUE)
  {
   k=kbd_getc();
   if(k!=0)
     {
      if(k=='*')
         printf("%c", '*');
      else
         printf("%c", k);
     }
  }

}

it is work very well I changed 18f452 with 16f877A it work good too, but when I changed header with 18f26k20 OR 18f46k20 it doesn't work. Then after search in the forum I understood that I should use pull up resistor for row, after this it work and but after 3 or 4 press it doesn't work.
My simulator program is Proteus and my compiler is CCS4.13
and it is my header code with 18f26k20:

Code:

#include <18F26K20.h>
#device adc=10
#FUSES HS                       //High speed Osc (> 4mhz)
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES LP                       //Low power osc < 200 khz
#FUSES NOBROWNOUT               //No brownout reset
//#FUSES WDT_NOSLEEP              //Watch Dog Timer, disabled during SLEEP
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES INTRC      // setup internal oscillator

Sincerely yours
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Aug 22, 2013 9:48 pm     Reply with quote

That's not my keypad code. That's Ahmed's code, from the Code Library.

Quote:

#include <18F26K20.h>
#device adc=10
#FUSES HS //High speed Osc (> 4mhz)
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES LP //Low power osc < 200 khz
#FUSES NOBROWNOUT //No brownout reset
//#FUSES WDT_NOSLEEP //Watch Dog Timer, disabled during SLEEP
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES INTRC

Also in the code above, you have three different oscillator fuses. You
should only have one.


Quote:
but when I changed header with 18f26k20 OR 18f46k20 it doesn't work

When you change to a new PIC and it doesn't work, read the Migration
document for the new PIC. It's named:

PIC18F4520 → PIC18F45K20 Migration
http://ww1.microchip.com/downloads/en/DeviceDoc/41310A.pdf
Read about the pull-up differences at the top of page 3:
Quote:

The RBPU bit is still the global weak pull-up enable and the WPUB register
powers-up with all pull-ups enabled to preserve the functionality of the
WPUA bit for legacy code. Where as the internal weak pull-up resistors on
inputs were globally enabled or disabled on the PIC18F4520, the
PIC18F45K20 has independent control of the weak pull-ups
, where
each pull-up has a control bit in the WPUB register.


Then read the 18F26K20 data sheet:
Quote:

10.3.1 WEAK PULL-UPS
Each of the PORTB pins has an individually controlled weak internal
pull-up. When set, each bit of the WPUB register enables the corresponding
pin pull-up.

Next, look up this function in the CCS manual:
Code:
port_b_pullups(true);

It says:
Quote:

Parameters: value is TRUE or FALSE on most parts, some parts that allow pullups to be specified on individual pins permit an 8 bit int here, one bit for each port pin. upmask for ports that permit pullups to be specified on a pin basis. This mask indicates what pins should have pullups activated. A 1 indicates the pullup is on


In other words, to turn on all pull-ups, you do this:
Code:
port_b_pullups(0xFF);

or
Code:
port_b_pullups(0b11111111);
[email protected]



Joined: 22 Aug 2013
Posts: 22

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

PostPosted: Fri Aug 23, 2013 2:35 am     Reply with quote

thank you PCM programmer for your good suggestion I read data and links that you sent, but with when I changed the code, it doesn't work again. I can't understand why I need internal pull up when I used external pull up?
this is my last Code:
Code:
#include <18F26K20.h>
#device adc=10
#FUSES HS //High speed Osc (> 4mhz)
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
//#FUSES LP //Low power osc < 200 khz
#FUSES NOBROWNOUT //No brownout reset
//#FUSES WDT_NOSLEEP //Watch Dog Timer, disabled during SLEEP
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
//#FUSES INTRC
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

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

//Keypad connection:
#define row0 PIN_B4
#define row1 PIN_B5
#define row2 PIN_B6
#define row3 PIN_B7
#define col0 PIN_B0
#define col1 PIN_B1
#define col2 PIN_B2
#define col3 PIN_B3

// 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()
{
//set_tris_b(0xF0);
//output_b(0xF0);
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);
        output_high(col3);
        break;
   
      case 1:
        output_high(col0);
        output_low(col1);
        output_high(col2);
        output_high(col3);
        break;

      case 2:
        output_high(col0);
        output_high(col1);
        output_low(col2);
        output_high(col3);
        break;

      case 3:
        output_high(col0);
        output_high(col1);
        output_high(col2);
        output_low(col3);
        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==4)
            col=0;
        }
     }
   kbd_call_count=0;
  }
return(kchar);
}

//===========================
void main()
{
char k;
port_b_pullups(true);
kbd_init();
   port_B_pullups(0xFF);
   setup_timer_3(T3_DISABLED | T3_DIV_BY_1);

   setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard

printf("\r\Starting ...");

while(TRUE)
  {
   k=kbd_getc();
   if(k!=0)
     {
      if(k=='*')
         printf("%c", '*');
      else
         printf("%c", k);
     }
  }

}

really thanks for spending your time for solving newer Programmer like me Very Happy
[email protected]



Joined: 22 Aug 2013
Posts: 22

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

PostPosted: Sat Aug 24, 2013 9:45 pm     Reply with quote

any idea?
please help me after 2 days yet I can't solve my problem
I need your guides,
best regards.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Aug 24, 2013 10:43 pm     Reply with quote

Quote:
my compiler is CCS4.13

What's your real compiler version ? And why does nearly every newbie
leave off the last one or two digits of their version number ?
Ttelmah



Joined: 11 Mar 2010
Posts: 19498

View user's profile Send private message

PostPosted: Sun Aug 25, 2013 12:28 am     Reply with quote

On the pull-ups, nowhere did you tell us that you had got external pull-ups....
You know your hardware, we don't.

Critical thing is the compiler version.
Without this though add one fuse:

NOPBADEN

The chip defaults to setting portB, as _analog_, unless this fuse is selected.
Some compiler versions will default to selecting this fuse.

Best Wishes
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Aug 25, 2013 12:42 am     Reply with quote

That's why I wanted to know his version. I had checked, and in vs. 4.141
if you don't specify the fuse, it defaults to PBADEN (analog for PortB).
But, the startup code sets PortB to digital i/o, overriding the fuse.
Code:

00028:  MOVF   ANSELH,W
0002A:  ANDLW  E0
0002C:  MOVWF  ANSELH

His version may not do that.
Ttelmah



Joined: 11 Mar 2010
Posts: 19498

View user's profile Send private message

PostPosted: Sun Aug 25, 2013 12:57 am     Reply with quote

Exactly.

I tested a low 4.13x version, and it doesn't.

This is why version numbers x.xxx, are so critical.

Best Wishes
[email protected]



Joined: 22 Aug 2013
Posts: 22

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

PostPosted: Tue Aug 27, 2013 1:01 pm     Reply with quote

Hi, thank you for replying & really very good support, your good support that was one of my reason for selecting CCS.
My compiler in PC is 4.13 and in my laptop PCWHD 4.140 but in both of them I have this problem.
I solved my keypad problem by changing the keypad function in the row for, I add delay_ms(10); my problem solved till I used uart channel two, when I used uart2 my keypad doesn't work, refer 18f46k22 datasheet I should set register of each port for using digital I/O & each port has ANSEL register, for example ANSELA, ANSELB , ANSELC &... but refer your guide and.... you said I should use just set ANSELH, & can you describe your code:
Code:

00028:  MOVF   ANSELH,W
0002A:  ANDLW  E0
0002C:  MOVWF  ANSELH

& if I want to change other port like PORTA to digital I/O what I should do?
Also I don't understand how I can set ANSEL A,B & ...
and in the end please suggest an ebook to learn something like these,
it is my simple keypad code:
Code:

#include <18F46K22.h>
#device adc=16
#fuses HSH,PUT,NOPROTECT,NOLVP,NOWDT,NOBROWNOUT,NOPLLEN,NOPBADEN,NOXINST

#use delay(clock=20000000)                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode) 

#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,stream=S1, ERRORS)
#use rs232(baud=9600, xmit=PIN_D6, rcv=PIN_D7,stream=XBEE, ERRORS)




//------------------
//keypad start
//------------------
//Keypad connection:
#define row0 PIN_B4
#define row1 PIN_B5
#define row2 PIN_B6
#define row3 PIN_B7
#define col0 PIN_B0
#define col1 PIN_B1
#define col2 PIN_B2
#define col3 PIN_B3

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


#define KBD_DEBOUNCE_FACTOR 100 // 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);
}



int8 keypad()
{
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);
        output_high(col3);
        break;
   
      case 1:
        output_high(col0);
        output_low(col1);
        output_high(col2);
        output_high(col3);
        break;

      case 2:
        output_high(col0);
        output_high(col1);
        output_low(col2);
        output_high(col3);
        break;

      case 3:
        output_high(col0);
        output_high(col1);
        output_high(col2);
        output_low(col3);
        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;
         delay_ms(10);//I insert this line and it correct my problem a bit
         if(col==4)
            col=0;
        }
     }
   kbd_call_count=0;
  }
return(kchar);
}
//-------------------
//end of keypad
//-------------------




void main()
{
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256|RTCC_8_bit);      //13.1 ms overflow

   setup_timer_3(T3_DISABLED | T3_DIV_BY_1);
   setup_timer_4(T4_DISABLED,0,1);
   setup_timer_5(T5_DISABLED | T5_DIV_BY_1);
   setup_timer_6(T6_DISABLED,0,1);

   setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
   enable_interrupts(INT_RTCC);
   enable_interrupts(int_rda);// rs232 hardware 1 interrupt 
   enable_interrupts(GLOBAL);
   char k;
   kbd_init();//intial keypad
   printf(S1,"hi GOD");
while(TRUE)
  {

           k=keypad();
   if(k!=0)
     {
      if(k=='*')
         fprintf(S1,"%c", '*');
         
      else
         fprintf(S1,"%c", k);
       
  }
  }

}

really thanks,
Sincerely yours.
Ttelmah



Joined: 11 Mar 2010
Posts: 19498

View user's profile Send private message

PostPosted: Wed Aug 28, 2013 4:59 am     Reply with quote

setup_adc(NO_ANALOGS);

There is no such compiler version as 4.13. 4.013?. If so, forget it and put 4.140 on the system. Version numbers are always x.xxx. The earliest V4 compiler that worked reasonably, was about 4.070.
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