PIC12F675 Switch I/O

Thread Starter

RodneyB

Joined Apr 28, 2012
697
I am VERY VERY new at writing code and am basically trying to teach myself C

I am writing a routine to push a button and an LED will come on for a short period then switch off. What I am wanting to add now is that when the button is pushed the output is checked first. If it is high it ignores the push button if low it goes high.

I have no idea how

My code thus far is

Rich (BB code):
if(SW1==0)// switch pushed
{ __delay_ms(100); // debounce delay
}
if(SW1==0)// switch still pushed
{
LED=1;// turn on LED1
__delay_ms(1000); //Delay
LED1=0; //Turn LED1 off
}
 

MrChips

Joined Oct 2, 2009
30,810
Writing code is the last thing you want to do.
Before you start writing code, lay out the flow of the code using flowcharts or pseudo-code.

Pseudo-code is the algorithm of your solution written out it plain English. I will provide an example of what is known as Structured Programming.

An IF-THEN-ELSE structure is written out as:

Rich (BB code):
IF (some condition)
THEN (process A)
ELSE (process B)
Edit: You don't need to use the braces ( ).

Rich (BB code):
IF some condition
THEN process A
ELSE process B
Recognize that in your example you need to test two conditions, the switch and the status of the LED. One possible solution would involve two nested IF-THEN-ELSE structures:

Rich (BB code):
IF (switch pushed)
THEN

  IF (LED is on)
  THEN (do nothing)
  ELSE (turn on LED for 1 second)

ELSE (do nothing)
You can reverse the logic as follows:

Rich (BB code):
IF (switch pushed)
THEN

  IF (LED is not on)
  THEN (turn on LED for 1 second)
  ELSE (do nothing)

ELSE (do nothing)
Since the ELSE (do nothing) is redundant, it can be eliminated:

Rich (BB code):
IF (switch pushed)
THEN

  IF (LED is NOT on)
  THEN (turn on LED for 1 second)
Another solution would be to combine the two tests into one boolean test:

Rich (BB code):
IF (switch pushed AND LED is NOT on)
THEN (turn on LED for 1 second)
One final word:

Since your 1-sec delay is inside your process, when your program exits from the process the LED will always be OFF. Hence all of the above code is unnecessary.

The above example applies to any programming language, not only C or ASM.
In C, the IF-THEN-ELSE structure is coded as

Rich (BB code):
  if (condition)
  { process A }
  else
  { process B }
Careful analysis before beginning to write code can save you a lot of time and effort.
 
Last edited:

Thread Starter

RodneyB

Joined Apr 28, 2012
697
Thank you this is extremely helpful

How would I code this ,

Is output high, if high wait tell low when low check if the switch is pushed, wait for de bounce then check switch again if still pushed turn on output for a set period then switch off.

It would be in a forever loop
Rich (BB code):
 while(1)
What I don't understand is how you get it to wait for that condition?
 

takao21203

Joined Apr 28, 2012
3,702
jump backwards as long as it is not satisfied.

Rich (BB code):
reloop:;

if(condition != condition_true) goto reloop;
Some people use a while loop:

Rich (BB code):
while(!condition);
Sometimes you'd want to branch if the condition is fulfilled, otherwise continue. Then you can use the main() while loop.
 

takao21203

Joined Apr 28, 2012
3,702
It must be said that condition testing loops just on their own are very bad programming practice.

If the condition is not met, your program essentially hangs.

For this reason, timeout is used with interrupts.


You can test the IO with interrupt, and in your main code, you test a key variable. If it was pressed and released, you branch to some code, and reset the key variable.

For the microcontrollers the timer is very important for program flow, so you should learn about it from early on.
 

Thread Starter

RodneyB

Joined Apr 28, 2012
697
My Sincere thanks for your help, I will take your advice 100% ! Firstly I will try the loop and then after that will go to the interrupt.

It is extremely helpful to know that something is bad programming practice, I feel often as a beginner we tend to never find the full potential of something once something works because we never are encouraged to explore other alternatives, however your reply has opened a new door for me. THANKYOU!!
 

ErnieM

Joined Apr 24, 2011
8,377
This looks like an excellent task to begin learning C for micros. One button to debounce, one LED to light, simple and direct but building on concepts needed for more advanced works.

For a one-task process such as this I would not worry about an interrupt check: if no one pressed the button for 3 days, so what? The LED doesn't light and all is well.

When more tasks get added, a more involved button test is needed, such that if the button is not pressed other tasks may run.

An alternate to an ISR to keep things active (in case of a crash) is the watchdog timer: active and correctly running code can reset the watchdog timer, but an error that halts the code running will not reset the watchdog, and the watchdog will then do a reset of the processor so you start as if the power was just applied.

But again, that's not for today but a later project.

Keep at it and good luck!
 

Thread Starter

RodneyB

Joined Apr 28, 2012
697
After an extremely frustrating day of trying to get a simple push button to switch on an LED for 10 seconds I have had to give up and ask for help.

The idea was to actually get an LED to switch on for 10 Seconds then switch off and loop forever so each time the switch is pushed the LED comes on. I also tried to check the output in all honesty I have no idea what's going on anymore.

Rich (BB code):
    if(SW1==0)
   {__delay_ms(100);}
   else(SW1==1);
   {__delay_ms(100);}
   if(SW1==1)
   
   {LED1=1;
  
 __delay_ms(1000);
           
  LED1=0;} 
   }
 

takao21203

Joined Apr 28, 2012
3,702
you should get a compiler warning about this:

Rich (BB code):
else(SW1==1)
I'd recommend to write C language with proper indention,
and always use the opening/closing braces.

Later you can omit them.

But this practice makes it easier to "read" C language source.

What is SW1? A variable, or does it point to a port bit?
What version of MPLAB do you use? MPLABX?

I'd recommend it, and if so, you can use project templates. All the neccessary files are generated, including for the interrupt.


You only need to:
-Enable GIE and TMR0IE
-Set the TIMER0 options
-Test in the ISR if TMR0IF was set, and reset

You could then program something like that in the main rountine:

-in the ISR you set a flag: tmr_flag|=1

-in the main routine, you test for this flag, and branch.

-if it was set, you reset it: tmr_flag&=0xfe
Then you increase a counter each time in this branch.

-later in main you test this counter for let's say, 0x30
So you can get a 16bit timer with software help.

You can blink a LED with that!

-If the test was true, you branch.
Reset the counter to 0. Toggle a LED flag:

Rich (BB code):
if(tmr_flag&0x02)tmr_flag&=0xfd;else tmr_flag|=0x02;
if(tmr_flag&0x02)PORTB.PORTBbits=1;else PORTB.PORTBbits=0;
As a result of this, you don't need to use any delay anymore.

I'd also recommend to select the Software Simulator in the project options, and then do single step debugging.

Latest MPLAB will display the variable values, if you hover over them. with F8, you can single step each C line (after setting an initial breakpoint).

So you can learn about what your code is doing.

Honestly, sometimes I am not exactly sure, and need to use the single step debugger + variables watch. It is all built into MPLABX now for free.
 

jjw

Joined Dec 24, 2013
823
You can detect the switch press assuming sw1==0 when pressed:

Rich (BB code):
while (sw1==1);  /* wait switch pushed */
delay();   /* debounce*/
if (sw1==0)  /* still pressed ? */
{    led1=1;
      ...  and so on 

}
and the whole block inside forever loop.
 

ErnieM

Joined Apr 24, 2011
8,377
Since you are having trouble, let's take a step back and make a very simple "press button LED goes on" program. It would look like so:

Rich (BB code):
    while(1)
    {
        if (SW1 == 0)        // switch pushed
        {
            LED1 = 1;        // turn on LED1
        }
        else
        {
            LED1 = 0;        // Turn LED1 off
        }
    }
Now mind you, several important pieces are missing here:

1 - There are no configuration settings

B - The symbols SW1 and LED are not defined.

iii - There is no main() function that is called when the program starts.

IV - The number zero sometimes means the button is pressed, sometimes means the LED is off, but in both cases it's effect seems magical. A symbol (or three) would better serve here.
 
Top