pic12f683 push button problem

Thread Starter

le2dangerous

Joined Jan 11, 2020
12
Hi i just joined to try and get a little help after getting no further with my project all day.
my project is one push button and one LED.
my goal was to get the push button to swap from 1 mode to another and then off (reset to 0)
i am new to all this so i got bits of code from here and there and broke it down and managed to get were i am now.
when i press the push button it goes from off (0) to mode 3 and stays on mode 3 flashing when i press the button again the led goes off.
why does it not go to mode one and stay there?
here is the code



C:
#pragma config FOSC = INTOSCIO  // Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
#pragma config WDTE = OFF        // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF      // MCLR Pin Function Select bit (MCLR pin function is digital input, MCLR internally tied to VDD)
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = OFF      // Brown Out Detect (BOR disabled)
#pragma config IESO = OFF       // Internal External Switchover bit (Internal External Switchover mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)


#include <xc.h>
#define _XTAL_FREQ 4000000

int main()
{
 
    TRISIO = 0;           //RB0 as output PIN
    ANSEL = 0;            // all outputs digital !!!!!
    CMCON0 = 7; 
    
    GP1 = 0;
    GP0 = 0;

    int mode = 1;
    
    while(1)
    {
        if(GP1 == 1)
        {
         __delay_ms(100);
          if(GP1 == 1)
          {
              mode++;
              GP1 = 0;
          }
        }
        
        if(mode >= 4)
        {
          mode = 0;
        }

        if(mode == 2)
        {
          GP0 = 1;
          __delay_ms(1000);
          GP0 = 0;
          __delay_ms(1000);
        }
        
        if(mode == 3)
        {
          GP0 = 1;
          __delay_ms(500);
          GP0 = 0;
          __delay_ms(500);
        }
    }
}
thank you
 

jpanhalt

Joined Jan 18, 2008
9,796
I know it takes a lot of lines in some languages, Try this:
Code:
   movlw     b'00000010'    ;toggle LED
   xorwf     GPI0,f         ;     "
When GPIO,1 =1, the LED goes off. When it equals 0, the LED will turn on. Of course,you will need to add your delays.
 

Thread Starter

le2dangerous

Joined Jan 11, 2020
12
I would like to stay with the same code because i been trying to grasp a little for days so i can understand it to a extent.
The bush button will be replaced by another circuit pulling up GP1.
I don't understand any of the code you posted but impressive the little it required.
I would also like to understand why it not working?
 

Thread Starter

le2dangerous

Joined Jan 11, 2020
12
I know it takes a lot of lines in some languages, Try this:
Code:
   movlw     b'00000010'    ;toggle LED
   xorwf     GPI0,f         ;     "
When GPIO,1 =1, the LED goes off. When it equals 0, the LED will turn on. Of course,you will need to add your delays.
looks like it compiled already :)
 

AlbertHall

Joined Jun 4, 2014
10,070
if(GP1 == 1) { __delay_ms(100); if(GP1 == 1) { mode++; GP1 = 0; } }
If the button is connected to GP1 and is set as an input then 'GP1=0' does nothing.
If the button is pressed for say 300ms then this code will run perhaps three times, incrementing mode each time. After detecting that the button is pressed you could wait until it is released before proceeding with the rest of the program.
 

Thread Starter

le2dangerous

Joined Jan 11, 2020
12
Glad you got the point. For those 12Fxxx chips, I use GPIO. I don't/didn't know whether your compiler recognized "GP".
I am using MPLAB X IDE v5.30 to build.
Will also be further adding more code so need to understand what is happening in the code.
with the circuit in front of me it acts exactly like i described in my first post going to mode 3 flashing until second button press then goes off.
Goal is to one button to turn it from off to mode one with led flashing second press goes to mode 2 and speeds up the flashing.
When it is in mode 2 i will be adding more code to listen on another pin waiting to go hi and that will finally turn on another LED just stuck at this point so cant progress.
So yea recognizes GP
thanks.
 

Thread Starter

le2dangerous

Joined Jan 11, 2020
12
That is my full code. yes button GP1 in connected to button. how to stop it running 3 times? i did think about this and added the delay and recheck?
thanks
 

Thread Starter

le2dangerous

Joined Jan 11, 2020
12
Does the circuit ignore switch bounce?
After you have found GP1==1 then do 'while (GP1==1);' to wait until the button is released.
I am new to programming i try what you said but circuit now goes. one press mode one second press mode two third press off but then does nothing to further button presses.
i implemented it like so
Code:
if(GP1 == 1)
        {
         __delay_ms(100);
          if(GP1 == 1)
          { 
         while(GP1==1)
            {
            }
          mode++;
          }
        }
what is switch bounce? i think it does not.
thanks
 

AlbertHall

Joined Jun 4, 2014
10,070
I would expect it to take two further presses to get back to lighting the LED. At the start of the program mode is initialised to '1' but when mode reaches 4 it is reset to '0'. It should be reset to '1' but I don't think that will fix all the problem but try it anyway.

if(mode >= 4) { mode = 1; }
 

Thread Starter

le2dangerous

Joined Jan 11, 2020
12
ALL mechanical switches bounce. Here is a common reference on the matter: http://www.ganssle.com/debouncing.pdf
Is this my problem? looks over my head.
I would expect it to take two further presses to get back to lighting the LED. At the start of the program mode is initialised to '1' but when mode reaches 4 it is reset to '0'. It should be reset to '1' but I don't think that will fix all the problem but try it anyway.

if(mode >= 4) { mode = 1; }
I made this change and now goes mode one then off then nothing.
thank you

i looked over bounce part one part 2 and don't see this implemented in other similar projects like blinking LED with push button although my button does seem to act differently on different kinds of presses?
 
Last edited:

Thread Starter

le2dangerous

Joined Jan 11, 2020
12
My end Goal is to have one button 2 LED's
first press will turn on 2 LED's
Second press will turn off the LED's and wait for another pin to go high
when a EMF circuit triggers this will pull up the other pin and flash the LED's but stuck at the current stage.

This is my full code up to now with changes, trying to get 2 modes with different sequences on the LED's with one push button.
Code:
#pragma config FOSC = INTOSCIO  // Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
#pragma config WDTE = OFF        // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF      // MCLR Pin Function Select bit (MCLR pin function is digital input, MCLR internally tied to VDD)
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = OFF      // Brown Out Detect (BOR disabled)
#pragma config IESO = OFF       // Internal External Switchover bit (Internal External Switchover mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)


#include <xc.h>
#define _XTAL_FREQ 4000000

int main()
{

    TRISIO = 0;           //RB0 as output PIN
    ANSEL = 0;            // all outputs digital !!!!!
    CMCON0 = 7;
   
    GP1 = 0;
    GP0 = 0;

    int mode = 1;
   
    while(1)
    {
        if(GP1 == 1)
        {
         __delay_ms(100);
          if(GP1 == 1)
          {  
         while(GP1==1)
            {
            }
          mode++;
          }
        }
        if(mode >= 4)
        {
          mode = 1;
        }

        if(mode == 2)
        {
          GP0 = 1;
          __delay_ms(1000);
          GP0 = 0;
          __delay_ms(1000);
        }
       
        if(mode == 3)
        {
          GP0 = 1;
          __delay_ms(500);
          GP0 = 0;
          __delay_ms(500);
        }
    }
}
thanks
 

AlbertHall

Joined Jun 4, 2014
10,070
At the start of the program you set TRISIO to '0'. This sets all pins to outputs so I don't know why it works as well as it does. Set TRISIO to 0x02 so GP0 is set as an output and GP1 is set as input.
 

Thread Starter

le2dangerous

Joined Jan 11, 2020
12
All mechanical switches bounce when closed, giving a number of rapid pulses for a number of milliseconds.
To ignore that, you can delay looking for a second pulse for about 50-100ms after the first pulse is detected.
At the start of the program you set TRISIO to '0'. This sets all pins to outputs so I don't know why it works as well as it does. Set TRISIO to 0x02 so GP0 is set as an output and GP1 is set as input.
I did what you recommended and now it does nothing. i do not understand the 0x02 bit but yea it stopped doing anything.
TRISIO = 0x02; //sets GP0 to output and GP1 to input


thanks
 

AlbertHall

Joined Jun 4, 2014
10,070
This version of the code (your version from post #15 with a couple of changes) works correctly in the simulator.
C:
#pragma config FOSC = INTOSCIO  // Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
#pragma config WDTE = OFF        // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF      // MCLR Pin Function Select bit (MCLR pin function is digital input, MCLR internally tied to VDD)
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = OFF      // Brown Out Detect (BOR disabled)
#pragma config IESO = OFF       // Internal External Switchover bit (Internal External Switchover mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)


#include <xc.h>
#define _XTAL_FREQ 4000000

int main()
{

    TRISIO = 0x02;           //RB0 as output PIN
    ANSEL = 0;            // all outputs digital !!!!!
    CMCON0 = 7;
   
    //GP1 = 0;
    GP0 = 0;

    int mode = 1;
   
    while(1)
    {
        if(GP1 == 1)
        {
         __delay_ms(100);
          if(GP1 == 1)
          {  
         while(GP1==1)
            {
            }
          mode++;
          }
        }
        if(mode >= 4)
        {
          mode = 1;
        }

        if(mode == 2)
        {
          GP0 = 1;
          __delay_ms(1000);
          GP0 = 0;
          __delay_ms(1000);
        }
       
        if(mode == 3)
        {
          GP0 = 1;
          __delay_ms(500);
          GP0 = 0;
          __delay_ms(500);
        }
    }
}
 

Thread Starter

le2dangerous

Joined Jan 11, 2020
12
Strange i have 4v to the pic, wire from + to switch that drives pin GP1 high on press and LED on GP0+ and vss-.
Does nothing with that code copy and pasted build with MPLAB X IDE v5.30 written to chip and put in that circuit??
appreciate the help thanks
 
Last edited:
Top