0

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;
                }
            }
        }
    }
}
Tinu
  • 19
  • 4
  • IMO you should use a PWM output and an interrupt input, currently, your input is only verified every 500ms after the first press, and for about a fraction of a second, thus explaining why you never trigger it. – Alexandre Lavoie May 12 '15 at 05:50

3 Answers3

0

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.

LPs
  • 16,045
  • 8
  • 30
  • 61
  • _Using a double while to catch an input causes that both IF can be valid thousand of times until you release the pushbutton._ well they can't since there are two delays. The second verification is made one time every 500ms, but will probably pass the first loop also. – Alexandre Lavoie May 12 '15 at 06:16
  • @ Alexandre when the led is blinking and the pushbutton is pressed (return to the first while) no delay is performed and the code immediately return to the inner loop. – LPs May 12 '15 at 06:19
0

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

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 ;
}
Kaz
  • 1,047
  • 8
  • 18
DILIP
  • 1