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

PIC12F675 Delay Question

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



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

View user's profile Send private message

PostPosted: Wed May 27, 2015 3:02 pm     Reply with quote

I'm not exactly sure I understand what you are trying to do but these look like early programming exercises. Perhaps for school or self study, but the only way you will learn is by trying yourself and making mistakes.

From the code you posted I can see you have just started to learn programming.

As Ttelmah said, the goto-statement is considered a bad programming practice and is best to never be used any more. There are some special cases where the goto-statement is useful but those are for advanced use only and, for now, forget about this instruction.

When you want to make a loop that never exits, then you code something like this:
Code:
while (TRUE) {
   // your code here
}
The advantage over using the goto-statement here is that your code is easier to read. The code is now 'self documenting' because it 'says' you want to do a loop.

I suggest you do some more reading in your C-language book over the while-loop because you repeat a particular error in your code. For example:
Code:
   in2:  while (input(PIN_A0))
         output_LOW(PIN_A5);
The while command will repeat the statement directly following this command. When I rewrite your code I can make this clear:
Code:
   in2:  while (input(PIN_A0))
         {
            output_LOW(PIN_A5);
         }
You are repeatedly setting PIN_A5 low for as long as PIN_A0 is high.
To avoid making mistakes like this it is good practice to always use the '{}' combination in while-loops and for-loops.

Ttelmah's suggestion for using a state machine and timer interrupts is very good but a bit too difficult for your programming knowledge.

Try to think about your problem in a different way by decoupling the switch logic and the timer into two separate steps. For example the next program will light a lamp for 30 seconds after the user releases the button.
Code:
#include <12F675.h>
#FUSES XT, NOWDT

#use delay(clock=4MHz)

#define SECONDS_1     (100 * 10)        // 100 x 10 ms == 1 second
#define SECONDS_30    (30 * SECONDS_1)

#define LAMP_BUTTON    PIN_A0
#define LAMP           PIN_A5

void main()
{
   int16 lamp_button_counter = 0;

   while(TRUE)
   {
      delay_ms(10);

      // If user pressed lamp button
      if (input(LAMP_BUTTON))
      {
         output_high(LAMP);
         lamp_button_counter = SECONDS_30;
      }

      // if lamp timer active
      if (lamp_button_counter > 0)
      {
         // Decrease lamp timer
         lamp_button_counter--;
         
         // Has timer expired?
         if (lamp_button_counter == 0)
         {
            output_low(LAMP);
         }
      }
   }
}
You can use this code as a base to expand.
Note how the use of #define makes the program easier to read.
corgenius



Joined: 27 May 2015
Posts: 18

View user's profile Send private message

PostPosted: Wed May 27, 2015 10:27 pm     Reply with quote

Dear ckielstra,

First of all I want to thank you for your time. This is exactly the type of code that I've been searching for:).
I've compiled it before work but I didn't manage to make the led blink. I will post some result as soon as I get home.


Ttelmah, also thank you for your time.


Warm regards,

Eugeniu
ckielstra



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

View user's profile Send private message

PostPosted: Thu May 28, 2015 1:58 am     Reply with quote

One thing to check is the switch logic. In my example program the switch input is high when the switch is pressed. I see your program has this reversed.
corgenius



Joined: 27 May 2015
Posts: 18

View user's profile Send private message

PostPosted: Thu May 28, 2015 8:45 am     Reply with quote

Dear ckielstra,

I've tried modifying the code in order to make the led blink. I even tried making a simple LED that is connected to PIN_A5 to blink, but with no success. I've tried to turn the LED ON with

Code:
#include <12F675.h>
#FUSES XT, NOWDT

#use delay(clock=4MHz)

#define SECONDS_1     (100 * 10)        // 100 x 10 ms == 1 second
#define SECONDS_30    (30 * SECONDS_1)

#define LAMP_BUTTON    PIN_A0
#define LAMP           PIN_A5


void main()
{
   port_a_pullups (0x01);

      // If user pressed lamp button
      if (!input(PIN_A0))
      {
         output_HIGH(PIN_A5);
      }
}


, but also 0 success:(.

Do you have any idea why the code doesn't work?




Regards,

Eugeniu
dyeatman



Joined: 06 Sep 2003
Posts: 1924
Location: Norman, OK

View user's profile Send private message

PostPosted: Thu May 28, 2015 9:46 am     Reply with quote

The chip won't run without a clock. You are using the XT fuse.
A5 is normally an Xtal input and you don't have an Xtal.
In your fuses change XT to INTRC_IO to enable the
internal osc and make A5 (GP5) an output. You need to read the datasheet.
_________________
Google and Forum Search are some of your best tools!!!!
corgenius



Joined: 27 May 2015
Posts: 18

View user's profile Send private message

PostPosted: Thu May 28, 2015 12:25 pm     Reply with quote

Dear colleagues,

I've modified the code so the LED will "blink", but, for a continuous input (like I have in my project, the LED will not go off :(.

I've tryied changin the
Code:
  if (!input(LAMP_BUTTON))
         {
          output_high(LAMP);
          lamp_button_counter = SECONDS_5;
         }
      // if lamp timer active
         if (lamp_button_counter > 0)
      {
         // Decrease lamp timer
         lamp_button_counter--;
         
         // Has timer expired?
         if (lamp_button_counter == 0)
         {
            output_low(LAMP);
into

Code:
  while (!input(LAMP_BUTTON))
         {
          output_high(LAMP);
          lamp_button_counter = SECONDS_5;
         }
      // if lamp timer active
         if (lamp_button_counter > 0)
      {
         // Decrease lamp timer
         lamp_button_counter--;
         
         // Has timer expired?
         if (lamp_button_counter == 0)
         {
            output_low(LAMP);


and many more combinations, but with no result :(. I even added a GOTO expression, but still no result.

My complete code is
Code:

#include <12F675.h>
#FUSES INTRC_IO
#define portOut1 pin_a5

#use delay(clock=4MHz)

#define SECONDS_1     (100 * 10)        // 100 x 10 ms == 1 second
#define SECONDS_5     (5 * SECONDS_1)

#define LAMP_BUTTON    PIN_A0
#define LAMP           PIN_A5

void main()
{
   port_a_pullups (0x01);
   int8 lamp_button_counter = 0;

   while(TRUE)
   {
      delay_ms(10);

      // If user pressed lamp button
      if (!input(LAMP_BUTTON))
         {
          output_high(LAMP);
          lamp_button_counter = SECONDS_5;
         }
      // if lamp timer active
         if (lamp_button_counter > 0)
      {
         // Decrease lamp timer
         lamp_button_counter--;
         
         // Has timer expired?
         if (lamp_button_counter == 0)
         {
            output_low(LAMP);
         }
      }
   }
}


Thank you again for your time and knowledge.

Regards,

Eugeniu
corgenius



Joined: 27 May 2015
Posts: 18

View user's profile Send private message

PostPosted: Sat May 30, 2015 9:41 am     Reply with quote

Dear colleagues,

I've tried adding a counter, in order to make the loop run just once when the input is continuously 1, but I didn't had any luck. The loop runs once, even though the input stays 1, but after realizing the button and pressing it again the loop doesn't start again.

My code is:

Code:
#include <12F675.h>
#FUSES INTRC_IO
#define portOut1 pin_a5

#use delay(clock=4MHz)

#define SECONDS_1     (100 * 10)        // 100 x 10 ms == 1 second
#define SECONDS_5     (5 * SECONDS_1)

#define LAMP_BUTTON    PIN_A0
#define LAMP           PIN_A5

void main()
{
port_a_pullups (0x01);
int8 lamp_button_counter = 0;
int counter = 0;



while(counter < 1)
   {
      delay_ms(10);

      // If user pressed lamp button
      if (input(LAMP_BUTTON))
      {
         output_high(LAMP);
         lamp_button_counter = SECONDS_5;
      }

      // if lamp timer active
      if (lamp_button_counter > 0)
      {
         // Decrease lamp timer
         lamp_button_counter--;
         
         // Has timer expired?
         if (lamp_button_counter == 0)
         {
            output_low(LAMP);
            counter = counter + 1;
         }
      }
   }
 while (input(LAMP_BUTTON))
      {
         counter = 0;
      }   
}



I even tried using the !input in order to make the counter 0 again with
Code:
 while (!input(LAMP_BUTTON))
      {
         output_low(LAMP);
         counter = 0;
      }


No luck.

Any ideas as how I can fix this?

Regards,

Eugeniu
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat May 30, 2015 10:52 am     Reply with quote

You need to look for an edge instead of a level. Read the switch input,
and when it changes from the inactive level to the active (pressed) level,
then you can turn on your LED. Example:
http://www.ccsinfo.com/forum/viewtopic.php?t=53600&start=11
and more:

Here is the "Button Command" code that I wrote for the Code Library:
http://www.ccsinfo.com/forum/viewtopic.php?t=23837

Here's a version of it that polls the buttons during a timer interrupt:
http://www.ccsinfo.com/forum/viewtopic.php?t=31849

This version stores the button presses in a buffer, which can be read:
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