Electronic – I/O input output pic16f887

cmicrocontrollerpic

I'm trying to read a pushbutton press and turn a led in case its pressed. I have the following code. I have a 1k resistance with the LED and I'm connecting the push button directly to RD0. But the led is always on! If I disconnect vcc it kinda "works". What am I doing wrong?

#define _XTAL_FREQ 8000000

#pragma config FOSC = INTRC_CLKOUT, WDTE = OFF, PWRTE = ON      
#pragma config MCLRE = ON, CP = OFF, CPD = OFF, BOREN = OFF      
#pragma config IESO = ON, FCMEN = ON, LVP = OFF        

#include <xc.h>
#include <pic16f887.h>

void main() {
    PORTD = 0;
    TRISD = 0;
    TRISD0 = 1;
    RD1 = 0;
    OSCCON = 0x70;

    while (1) {
        if (RD0) {
            RD1 = 1;
        } else {
            RD1 = 0;
        }
    }
}

schematic

simulate this circuit – Schematic created using CircuitLab

Best Answer

When the button isn't being pressed, what state should RD0 read? High or low? Look at the schematic for a minute and think about it.

If you're unsure, that's good. Because the 16F887 is unsure as well. When the button isn't being pressed, RD0 is actually floating. Nothing is driving it up or down. Unfortunately, there is a no "meh" option for digital electronics. The MCU must choose high or low. Absent a driving force on RD0, the pin will act like a tiny antenna and may randomly change state with the local electric field around it. In your case, it sounds like it's sticking high. The electrostatic field around your hand may actually change the pin state if you bring your hand near the MCU.

The solution is to put a pull-down resistor on RD0. Any reasonably large value of resistance will work (4.7k, 10k, and 100k are very common values). This will provide a driving force to 0V when the button isn't being pressed. When the button is pressed the resistor will appear negligible and the pin will see 5V.

Related Topic