View previous topic :: View next topic |
Author |
Message |
Sid2286
Joined: 12 Aug 2010 Posts: 119
|
keypad not working |
Posted: Thu Sep 02, 2010 10:08 pm |
|
|
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
|
|
Posted: Fri Sep 03, 2010 1:52 am |
|
|
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
|
|
Posted: Fri Sep 03, 2010 2:08 am |
|
|
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
|
|
Posted: Fri Sep 03, 2010 5:05 am |
|
|
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
|
|
Posted: Fri Sep 03, 2010 5:55 am |
|
|
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
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
|
|
Posted: Fri Sep 03, 2010 6:00 am |
|
|
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
|
|
Posted: Fri Sep 03, 2010 6:01 am |
|
|
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
|
|
Posted: Fri Sep 03, 2010 7:21 am |
|
|
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
|
|
Posted: Fri Sep 03, 2010 10:42 am |
|
|
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
|
|
|
|