|
|
View previous topic :: View next topic |
Author |
Message |
SUPERMAN Guest
|
Can't read switches |
Posted: Sat Mar 28, 2009 3:45 pm |
|
|
I am trying to read momentary switches. If switch 1 gets pressed I want to print '1'.
I am trying to do this using port c of 16f873 but for some reason I can't even get the processor to go low when the switch is pressed.
Can someone please help.
The code is below.
Code: |
#include<16f873.h>
#use delay(clock = 4000000)
#fuses xt, nolvp, nowdt
main(){
output_c(0X00);
WHILE(1){
if (pin_c0 == 1)
{ printf(lcd_putc,"\n 1");
}}}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
AsmallGuy Guest
|
|
Posted: Sun Mar 29, 2009 4:07 am |
|
|
To get you straight to the point:
Code: |
while(1)
{
if (input(PIN_B1)==0) output_high(PIN_C1);
else output_low(PIN_C1);
delay_ms(50);
} |
This will drive PIN_C1 according to the state of PIN_B1, the delay is just to leave out some bounces (quick and dirty way..).
You could also implement that via interrupt on change instead of this polling method; this code is just as example, real implementation may vary according to your hardware, etc; you can implement the directive "fastIO" to preselect direction of the PINs and increments a lot I/O capabilities.
Hi ! |
|
|
SUPERMAN Guest
|
READING INPUT SWITCHES USING SWITCH CASE |
Posted: Sun Mar 29, 2009 1:24 pm |
|
|
Thank you very much. Am looking for another way around this
and heres is what I want to try next.
Do you think its gonna give me the desired result?
If I connect these momentary switches to say for example portB, and if I read the value on port b, knowing that, if the switches aren't pressed, the value on port b should read 0x00. Now if a switch gets pressed, that should change the value to 0x01, as long as the switch is continually pressed.
So if i was using a switch case to monitor the value on port b, if the value changes I want to use a switch case to output the corresponding value on port b. Thank you again.
Code: |
#include<16f873.h>
#fuses HS, NOWDT
#use delay (clock = 4000000)
void main()
{
unsigned char c;
port_b_pullups(TRUE);
set_tris_b(0XFF);
output_b(0x00); // am not so sure about this line but trying to
// make sure that the port b value when
// i read it shuould be all zeros
while(1)
{
c = input_b();
switch(c)
{
case '0': c = 0X01;
printf(lcd_putc,"\f 1 is pressed");
break;
case '1': c = 0X02;
printf(lcd_putc,"\f 2 is pressed");
break;
default: c = 0X00;
printf(lcd_putc,"\f nothing pressed");
}}} |
|
|
|
Ttelmah Guest
|
|
Posted: Sun Mar 29, 2009 1:32 pm |
|
|
Two big problems.
First, the 'output_b' statement, will _drive_ all the pins low. You don't want this...
Second, your tests, are looking for the wrong thing. The frst one for instance, will test for the whole byte coming from port B, being the _ASCII character_, '0'. This is the binary value 00110000, and if the switches are 'pull down', will require the switch on B7, 'on', B6 'on', B5 'off', B4 'off', and all the low four switches 'on'. Not what you want at all......
Best Wishes |
|
|
Guest
|
|
Posted: Sun Mar 29, 2009 2:44 pm |
|
|
Points noted thank you.
So wat if I read the instant value on port b, and then proceed to capture this value and store it in a variable. Next compare the stored value with a constant. If the result is true, then do printf. The corrected code is found below. thank u again
Code: |
#include<16f873.h>
#fuses HS, NOWDT
#use delay (clock = 4000000)
void main()
{
int c =0;
port_b_pullups(TRUE);
set_tris_b(0XFF);
while(1)
{
c = input_b();
if ( c == 0X01)
{
printf(lcd_putc,"\f 1 is pressed");
}
if (c == 0X02)
{
printf(lcd_putc,"\f 2 is pressed");
}
else
{
printf(lcd_putc,"\f nothing is pressed");
}
}
|
|
|
|
Ttelmah Guest
|
|
Posted: Sun Mar 29, 2009 2:56 pm |
|
|
Nearly there.
Remember that switches _pull low_. The whole port will sit with 1's being seen, when no switch is pressed. When you press a switch, you pull the line to 0. You need to invert the patterns you are looking for.
Then, what happens if both switches are pressed?.
Best Wishes |
|
|
Guest
|
|
Posted: Sun Mar 29, 2009 5:40 pm |
|
|
Originally, I was going to implement a 3 x 4 keypad but writing a code for that was proving too tough. So I decided, well I can achieve the same thing if I wired switched directly to the port. That way for every switch i'd identify a unique address. For example if SW1 was wired to port b1, if that switch got pressed then i'd say, "1 pressed" I'd do the same thing again with a 2nd switch connected to port_b2, if that switch got pressed, i'd say, "2 pressed", but i had problem making my port recognice that i even had the switches connected to it. It remained high/ low and never went low/high when the switch got pressed. So to get around this I decided to read the whole port.
So to answer your question about what happens when 2 switches get pressed. If I am reading the port, then what am actually doing is counting in binary (provided I reverse the logic like u suggested). So for example, working with 2 switches will mean that the most output i'll get will be 2^2 = 4.
Or am I missing somthing here?
Again thanks for your advise. Its well noted
Pls find the corrected code. Is the instruction to use pull_up_resistors the reason why you say the port will be high when nothing is pressed?? Code: |
#include<16f873.h>
#fuses HS, NOWDT
#use delay (clock = 4000000)
void main()
{
int c =0;
port_b_pullups(TRUE);
set_tris_b(0XFF);
while(1)
{
c = input_b();
if ( c == 0XFE)
{
printf(lcd_putc,"\f 1 is pressed");
}
if (c == 0XFC)
{
printf(lcd_putc,"\f 2 is pressed");
}
else
{
printf(lcd_putc,"\f nothing is pressed");
}
}
|
|
|
|
|
|
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
|