Led on/off using PIC 16f777a

1.4k Views Asked by At

I am doing an exercise using push button. When the button is pressed once the led starts blinking and when it is pressed again it stops. When I tried the led is blinking on 1st press but it is not stopping on 2nd. I am using PIC16F877A MCU with HiTech C Compiler. My code is :

#include<pic.h>
#define _XTAL_FREQ 20000000

void main()
{
 TRISB = 0x01;
 PORTB = 0x00;
 while(1){
if(RB0 == 1){
        while(1){
            PORTB = 0xff;
            __delay_ms(250);
            PORTB = 0x00;
            __delay_ms(250);
            if(RB0 == 1){
                break;
                }
            }
        }
    }
}
3

There are 3 best solutions below

2
LPs On BEST ANSWER

I think is a "too short" loop.

Using a double while to catch an input causes that both IF can be valid thousand of times until you release the pushbutton.

A suggest you to manage it on the release of button, that means you trigger the push of button and valid the push when the button is released.

A simple solution can be:

#include <pic.h>
#include <stdint.h>
#define _XTAL_FREQ 20000000

void main()
{
   unit8_t pressed = 0;
   bool blink = 0;

   TRISB = 0x01;
   PORTB = 0x00;
   while(1)
   {
       // Button pressed for the first time
       if ((RB0 == 1) && (pressed == 0))
       {
           pressed = 1;
       }
       // Button released = valid 
       else if ((RB0 == 0) && (pressed == 1))
       {
           pressed = 2;
       }

       if (pressed == 2)
       {
          blink ^= 1;
          pressed = 0;
       }

       if (blink == 1)
       {
          PORTB ^= 0xFE;
          __delay_ms(250);
       }
    }
}

With this very simple solution, elaborated from yours, you have always a "strange feeling" with the push button, because of there is a 250ms delay each loop (in your case 500ms) that means that you can loose a single button pressure.

Take notes also that with a simple input you have to manage debounce, also. When the contacts of any mechanical switch bang together they rebound a bit before settling, causing bounce. Debouncing, of course, is the process of removing the bounces, of converting the brutish realities of the analog world into pristine ones and zeros.

Anyway the best solution is to add a timer that manage the blink of led and use main loop to evaluate the button pressure. This avoid the delay between input checks.

0
AudioBubble On

I think you run too fast through your code (same as answer before).

If you press you get into the while. Press the button on the second if() is difficulty.

You should debounce your Buttons. To Trigger your Buttons you can use Interrupt on Change (falling rising edge) or Count the number of "pushes" in a timer Interrupt (look every x milliseconds if Port is low or high and increment a variable, if the Port has changed)

Hope this helps

0
DILIP On

when you touch the switch led should be on and the 2nd time you touch the switch led should be off.. pic16f1527 microcontroller.... this code is not working so anyone have solution.

include <xc.h>

int switchpressed(void){ // CREATE A FUNCTION FOR SWITCH PRESSED 1ST TIME
    if(TRISFbits.TRISF3==1){ 
        
    }
    return switchpressed;
}

int switchpressed2(void){ // CREATE A FUNCTION FOR SWITCH PRESSED 2ND TIME
    if(TRISFbits.TRISF3==1){
        
    }
    return switchpressed2;
}

void main(void) {
    ANSELFbits.ANSF3 = 0; // RF3 AS DIGITAL PIN
    
    TRISFbits.TRISF3 = 1; // PORT RF3 AS INPUT PIN
    TRISBbits.TRISB5 = 0;  // RB5 OUTPUT PIN
    do{
        
        if(RF3== switchpressed()){
           PORTBbits.RB5= 1;
        } 
        if(RF3==switchpressed2()){
            PORTBbits.RB5= 0;
        }
    }while(1);

    return ;
}