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

simple led push button program

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



Joined: 04 Mar 2009
Posts: 19

View user's profile Send private message

simple led push button program
PostPosted: Wed Feb 10, 2010 11:49 am     Reply with quote

Hi there, I'm trying to make a simple push button program, which turns on a led when it is pressed and then turns it off when pressed again. I have connected the + side of the led to pin C4. The push button allows power to go to pin C3 when pressed. I'm using a pic16f877a.

This is the code I've been trying to use:
Code:

#include <16F877A.H>
#fuses XT, NOPROTECT, NOWDT, BROWNOUT, PUT, NOLVP
#use delay(clock=20000000)

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

void main()

{
   
      if(input(PIN_C3) == 1)
      {
         output_high(PIN_C4);
      }
      else if (input(PIN_C3) == 1 && input(PIN_C4) == 1 ){
      output_low(PIN_C4);
      }

     delay_ms(200);
}

Can anyone spot my mistake, it's driving me mad?

Thanks for your help
piire!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Feb 10, 2010 12:06 pm     Reply with quote

Study this demo program:
http://www.ccsinfo.com/forum/viewtopic.php?t=40707&start=5
piire



Joined: 04 Mar 2009
Posts: 19

View user's profile Send private message

PostPosted: Fri Feb 12, 2010 6:17 am     Reply with quote

Hi there

I looked at your code thanks alot, but I need to connect more leds to do other operation and this code wont work for this task.

Can I use the set_tris_ operation to set inputs and outputs to get this to work with if statements ?

How would i use the set_tris_ operation for input pin C3 and output C4. I don't understand how the set_tris_ works?

I'm using pic16f778a.

Thanks for your help.
piire!!
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Fri Feb 12, 2010 7:02 am     Reply with quote

You don't need to use tris statements.

You problem is that you are first using C4 as an output and the compiler configures it as an output when it first uses
OUTPUT_HIGH(PIN_C4);

BUT, when you try to read the value back
else if (input(PIN_C3) == 1 && input(PIN_C4) == 1 )

This re-configures it as an input.

You have 2 options.
Use INPUT_STATE(PIN_C4) to read its value without changing it's direction or use a flag to indicate the current setting of PIN_C4.

INPUT_STATE may be affected by what is known as the RMW Read, Modify, Write issue. But I don't think so.

I am sure someone else can shed some light on this.
ckielstra



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

View user's profile Send private message

PostPosted: Fri Feb 12, 2010 8:24 am     Reply with quote

Besides the problem mentioned by Wayne there is also a logical error:
Code:
      if(input(PIN_C3) == 1)
      ....
      else if (input(PIN_C3) == 1 && input(PIN_C4) == 1 ){
      ....
If the button on C3 is active, then the first test always will be executed and you never get to the 'else'.

You could solve this like:
Code:
      if (input(PIN_C3) == 1 && input_state(PIN_C4) == 1 )
      ....
      else if (input(PIN_C3) == 1 && input_state(PIN_C4) == 1 ){
      ....

A weak issue in this solution is the mentioned RMW problem; it is possible that external capacitances on the line causes the line not to have the output level you think it has. Better is to use a variable to keep track of the LED output status.

Code:
#include <16F877A.H>
#fuses XT, NOPROTECT, NOWDT, BROWNOUT, PUT, NOLVP
#use delay(clock=20000000)

#define BUTTON  PIN_C3
#define LED     PIN_C4

#define ON      0
#define OFF     1

void main()
{
  int8  LedStatus = OFF;
 
   while (TRUE)
   {   
      if ((input(BUTTON) == 1) && (LedStatus == OFF))
      {
         output_high(LED);
         LedStatus = ON;
      }
      else if (input(BUTTON) == 1 && (LedStatus == ON))
      {
         output_low(LED);
         LedStatus = OFF;
      }

     delay_ms(200);
   } 
}
aa7dj



Joined: 27 Apr 2007
Posts: 7
Location: St. George, UT

View user's profile Send private message

Oscillator Type
PostPosted: Fri Feb 12, 2010 10:24 am     Reply with quote

Quote:
#include <16F877A.H>
#fuses XT, NOPROTECT, NOWDT, BROWNOUT, PUT, NOLVP
#use delay(clock=20000000)



For 20 MHz fuse should be set to HS. See page 146 of PIC16F87xA Data Sheet.
piire



Joined: 04 Mar 2009
Posts: 19

View user's profile Send private message

PostPosted: Sun Feb 14, 2010 10:12 am     Reply with quote

Thanks alot for your help. The system works, I do sometimes have to press the button twice to turn the led on, but I guess thats to do with the processing power of the PIC.

Thanks alot got your all help!

piire!
ckielstra



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

View user's profile Send private message

PostPosted: Sun Feb 14, 2010 4:12 pm     Reply with quote

Quote:
I do sometimes have to press the button twice to turn the led on, but I guess thats to do with the processing power of the PIC.
Processing power is part of the problem, the PIC is too fast for your switch. Smile
A common problem in hardware switches is 'bouncing'. When the switch changes position it takes a little time to settle in the final position, it makes contact and then bounces back a few times. Depending on switch internals it can take up to 20ms to make final contact.
You'll have to add hardware for debouncing (a simple R/C combination on a Schmitt Trigger input) or add software debouncing (many implementations exist, the simplest is a delay of 20ms).
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