Search code examples
embeddedpicledhi-tech-c

Led on/off using PIC 16f777a


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;
                }
            }
        }
    }
}

Solution

  • 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.