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

keypad not working

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



Joined: 12 Aug 2010
Posts: 119

View user's profile Send private message

keypad not working
PostPosted: Thu Sep 02, 2010 10:08 pm     Reply with quote

Hi,

I have written a small program to check for a simple keypad. The switches are connected to port B and are further grounded.

Its frustrating cause I am not able to troubleshoot where the bug is:(
Please let me know where I'm going wrong.

Thanks a lot!

The code is as follows
Code:

void  scan()
 {
   if(PIN_B0==0)               //judge if B0 press
      result=0x1;
   if(PIN_B1==0)               //judge if B1 press
      result=0x2;
      result=0x0;              //initialize key scan result
 }

void main()


while(1)                 //dead circle
      {
        SET_TRIS_B(0XFF);
        scan();              //call key scan function
        display(result);     //call display result function
      };
   }
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Fri Sep 03, 2010 1:52 am     Reply with quote

For a start this is not a complete program, you will not get much help unless you post a compilable program which has your problem.

result will allways be 0 on the exit of this routine.
Code:

void  scan()
 {
   if(PIN_B0==0)               //judge if B0 press
      result=0x1;
   if(PIN_B1==0)               //judge if B1 press
      result=0x2;

   result=0x0;              //initialize key scan result
 }

I have altered the indentation and added a newline to show you how the code will be executed. it doesn't matter which if statement matches, your last line will always set result to 0x0.

Also, what does the display routine do ?
Most display routines output ascii characters to a display or rs232 (terminal). The characters 0x00, 0x01 and 0x02 are ascii control characters and may not show up on the display and if they do they won't be easily recognisable.
So unless display actually converts the value to a string to display on your output you may not be seeing what you expect.
Sid2286



Joined: 12 Aug 2010
Posts: 119

View user's profile Send private message

PostPosted: Fri Sep 03, 2010 2:08 am     Reply with quote

Thanks Wayne

I tried debugging using single step mode but I encounter that the loop is ignored. i.e my program is not read from if(pin_Bo==0) but jumps to the end of the loop.

The display routine only call few functions to display on seven segment.
The entire code is as follows
Code:

#include <16f877a.h>
#device ICD=TRUE ADC=8
#fuses HS,NOLVP,NOWDT
#use delay (clock=20000000)

 int i = 0;
 int  result;
 void  scan();               //key scan function declare
 void  display(int x);       //display function declare

#define P  0x8C
#define R  0xbb
#define O  0xA3
#define G  0x90
#define S  0x92
#define E  0x84
#define T  0x87
#define Z  0xbf


void prog()
{
   while(i<=100)
   {
   output_d(P);
   output_low(PIN_A5);
   delay_ms(1);
   output_high(PIN_A5);
   
   output_d(R);
   output_low(PIN_A4);
   delay_ms(1);
   output_high(PIN_A4);
   
   output_d(O);
   output_low(PIN_A3);
   delay_ms(1);
   output_high(PIN_A3);;
   
   output_d(G);
   output_low(PIN_A2);
   delay_ms(1);
   output_high(PIN_A2);
   
}
}

void scan()
 {
  if(PIN_B0==0)   //judge if B0 press
     result=0x1;
   if(PIN_B1==0)               //judge if B1 press
      result=0x2;

      result=0x0;             //initialize key scan result
 }




   void set()
   {
   while(i<=100)
   {
   output_d(S);
   output_low(PIN_A5);
   delay_ms(1);
   output_high(PIN_A5);
   
   output_d(E);
   output_low(PIN_A4);
   delay_ms(1);
   output_high(PIN_A4);
   
   output_d(T);
   output_low(PIN_A3);
   delay_ms(1);
   output_high(PIN_A3);;
   
   output_d(T);
   output_low(PIN_A2);
   delay_ms(1);
   output_high(PIN_A2);
   
   }
}

 void nothing()
 { while(1)
  {
   output_d(Z);
   output_low(PIN_A5);
   delay_ms(1);
   output_high(PIN_A5);
   
   output_d(Z);
   output_low(PIN_A4);
   delay_ms(1);
   output_high(PIN_A4);
   
   output_d(Z);
   output_low(PIN_A3);
   delay_ms(1);
   output_high(PIN_A3);;
   
   output_d(Z);
   output_low(PIN_A2);
   delay_ms(1);
   output_high(PIN_A2);
  scan();
  }
 }
   
  void  display(int x)
 {
   switch(x)                //different x,different deal
     {
      case 0x1:
         prog(); delay_ms(1);break;  //B0
      case 0x2:
         set(); delay_ms(1); break;  //B1
      case 0x0:
         nothing();delay_ms(1);break;  //no key press
      }
 } 
 
   
void main()


while(1)                 //dead circle
      {
        SET_TRIS_B(0XFF);
        port_b_pullups(false);
        //prog();
        //set();
        scan();              //call key scan function
        display(result);     //call display result function
      }
   }
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri Sep 03, 2010 5:05 am     Reply with quote

Code:
  if(PIN_B0==0)   //judge if B0 press
compare this to:
Code:
output_low(PIN_A3);
If you need a function to write to a pin, don't you think it logical to use a function to read from a pin too?

Just a few other notes:
Code:
#define P  0x8C
#define R  0xbb
#define O  0xA3
#define G  0x90
#define S  0x92
#define E  0x84
#define T  0x87
#define Z  0xbf
These defines do use very short names. This involves the risk of the name not being unique; the pre-processor will scan the program and replace every occurrence of the matching names with the defines. For example, if you have a variable in your code that is named 'S', than it will be replaced by your constant 0x92.
Best is to use longer names for your defines that will not easily match with other names. For example:
Code:
#define P  0x8C
#define CHAR_R  0xbb
#define CHAR_O  0xA3
#define CHAR_G  0x90
#define CHAR_S  0x92
#define CHAR_E  0x84
#define CHAR_T  0x87
#define CHAR_Z  0xbf


Code:

   output_high(PIN_A4);
On many PIC processors, including the PIC16F877a, the A4 pin is an open collector output. I don't know your circuit, but most likely you will have to add an pull-up resistor if you want to output a high voltage.
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Fri Sep 03, 2010 5:55 am     Reply with quote

LOL, I never spotted he hadn't got input(). lol

That wouldn't affect his current code though as he is still setting result to 0 at the end of the routine. He needs to do it before the if statements:-

Code:

void scan()
 {
  result=0x0;             //initialize key scan result

  if(input(PIN_B0)==0)   //judge if B0 press
     result=0x1;
   if(input(PIN_B1)==0)               //judge if B1 press
      result=0x2;

 }

That way if not key is pressed result is set to 0 but if either is pressed then it will be a different value.

I know I gave him the function there Smile

Even with this code though he should be seeing the output of the nothing routine. What are pins A2, A3, A4 and A5 connected to, what is the hardware layout for your display ?
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Fri Sep 03, 2010 6:00 am     Reply with quote

Just spotted another problem:-

Code:

void nothing()
 { while(1)
  {
   output_d(Z);
   output_low(PIN_A5);
   delay_ms(1);
   output_high(PIN_A5);
   
   output_d(Z);
   output_low(PIN_A4);
   delay_ms(1);
   output_high(PIN_A4);
   
   output_d(Z);
   output_low(PIN_A3);
   delay_ms(1);
   output_high(PIN_A3);;
   
   output_d(Z);
   output_low(PIN_A2);
   delay_ms(1);
   output_high(PIN_A2);
  scan();
  }
 }


You have an infinite loop in here and you call scan at the end of the routine. Once inside this loop it will not exit it!

I get the feeling you have 4 7 seg led displays and need to refresh them to keep the output!
A quick fix for this is to check result after you call scan and if it is not 0 break out of the routine.

Code:

void nothing()
 { while(1)
  {
   output_d(Z);
   output_low(PIN_A5);
   delay_ms(1);
   output_high(PIN_A5);
   
   output_d(Z);
   output_low(PIN_A4);
   delay_ms(1);
   output_high(PIN_A4);
   
   output_d(Z);
   output_low(PIN_A3);
   delay_ms(1);
   output_high(PIN_A3);;
   
   output_d(Z);
   output_low(PIN_A2);
   delay_ms(1);
   output_high(PIN_A2);
  scan();
  if (result)
    break;
  }
 }


But I think you need to be looking at a different method all together, look at using a timer interrupt!
Sid2286



Joined: 12 Aug 2010
Posts: 119

View user's profile Send private message

PostPosted: Fri Sep 03, 2010 6:01 am     Reply with quote

feels like you guys are pulling my leg :(
c'mon i am a newbie :'(

yes i later realized i was using result ==0 at the end and did the necessary changes. however i was still getting nothing.

well port A1,A2, etc are used to drive my seven segment.

I'm still dazing over how to write that function to read the input.
do help hint me if u can.

thanks guys...
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Fri Sep 03, 2010 7:21 am     Reply with quote

Reading the input it easy:-

Code:

void scan()
 {
  if(!input(PIN_B0))   //if B0 low result = 0x01
     result=0x01;
   else if(!input(PIN_B1))    //if B0 high and B1 low result = 0x02
      result=0x02;
  else
      result=0x00;             //Set to 0x00 if no input
 }



Your problem is mostlikely your output.

What do you see on the display ?
If you are using the debugger, then yo will most likely not see anything on the display when you have stopped the program to debug!
Your delays for the display output may be too low.

I need some info as to what is failing and an up to date posting of your code.
Sid2286



Joined: 12 Aug 2010
Posts: 119

View user's profile Send private message

PostPosted: Fri Sep 03, 2010 10:42 am     Reply with quote

Thanks program is working fine. However I feel I should be using timer for better efficiency.
Now I've never used timers before so might encounter problems again! Looking forward for your help. ;)
thanks alot guys.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Sep 03, 2010 12:50 pm     Reply with quote

Push-button code that is polled during a timer interrupt. There are two
versions of the code: With and without a buffer for the button presses.
http://www.ccsinfo.com/forum/viewtopic.php?t=39585&start=1
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