Electronic – GPIO on PIC16F887 not working

gpiomicrocontrollerpic

I've set the PIC16f887 on both external crystal 20MHZ and internal oscillator 4MHZ, neither of them ever worked with the following code:

int main(void) {

    ANSELbits.ANS5 = 0;

    TRISEbits.TRISE0 = 0; 
    PORTEbits.RE0 = 1;        // pin RE0 is high

    TRISDbits.TRISD1 = 0;    // pin RD1 is high
    PORTDbits.RD1 = 1;

    while(1);

    return 0;

}

But with the above two oscillator modes, I successfully worked out some UART functionality. So this might rule out the possibility of the PIC not working. At least I think so.

Just to be specific, my configuration bits for INTOSC are:

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

// CONFIG2
#pragma config BOR4V = BOR40V
#pragma config WRT = OFF

And as for external crystal, I just changed:

 #pragma config FOSC = HS

As I've read the datasheet over and over (maybe I still left out something important), I know the first thing to use a pin as general purpose I/O pin is to clear all the peripherals.
So I did

ANSELbits.ANS5 = 0;

to make sure RE0 is on digital input/output mode.

And I set the corresponding bit in TRIS register to configure the bit as output.

But it never worked.

update

I checked that the volts between VDD/VSS and RE0 are both zero, which confuses me quite a lot.

Does anybody know what is going on here?
FYI, I tested both PIC16f887s. They all ended up the same.

Best Answer

(this answer may not be accurate, please feel free to comment and edit)

After 2 days' looking into it, finally I have found several issues related and solved the problem.

When a microcontroller doesn't seem to work properly like the situation here, you might wanna check the following:

  1. Is all digital and analog supply and ground pins are properly connected?
  2. Is the microcontroller resetting itself repeatedly?
  3. Is oscillator working?
  4. Is the microcontroller in the programming mode instead of executing code?

After some testing and checking, I found the problem I had here is because I didn't implement reset and turned on the LVP(Low-volatge programming).

MCLR Reset

On some PICmirco devices, the MCLR(master clear) signal can be internally tied to VDD through a configuration bit MCLRE. If this bit is set, then the MCLR function is enabled. And then if the voltage on the pin is low, the microcontroller will have to reset. If this bit is clear, then the MCLR pin can be used as an I/O pin.

As for my problem here, I set the MCLRE bit but had MCLR pin floating. Since MCLRE bit is set, so the pin should function as input. But floating the pin made it hard to predict what's the voltage on it.

On PIC16F887 datasheet page 217, it suggests us tie a 1k(or greater) resistor to VDD and a 0.1uF(optional, not critical) capacitor to ground. Then microcontroller should never be resetting itself except POR,BOR and WDT timeout reset etc.

I actually replaced the capacitor with a switch, so I can manually reset the device whenever I want.

Low-voltage programming

I didn't realize that there is this LVP thing troubled me until I came across this post on Microchip forum.

Microchip provides us two programming mode: high-voltage programming and low-voltage programming.

High-voltage programming needed three things in sequence(according to PICmirco Device Programming: What You Always Wanted to Know (But Didn't Know Who To Ask) page 2) :

  1. Applying the appropriate power source and ground (VDD and VSS) to the device;
  2. Raising the voltage on the MCLR pin to the programming voltage level (in general, around 13V), while at the same time:
  3. Pulling the two designated I/O port to logic low and holding them there.

In case you haven't connected all the VDD and VSS appropriately, you should have. More info on this, check out If a PIC MCU provides multiple Vdd/Vss should you provide power to them all?.

The differences between the requirements on Low-voltage programming(also called Single-supply programming) and High-voltage programming is:

  1. Only VDD on the MCLR pin is required.
  2. LVP uses PGM as an additional programming pin, while other pins (PGC-Program Clock, PGD Program Data) in the High-voltage programming mode is still in use.

In my case, because in the configuration bits I set the LVP bit. As per the datasheet:

LVP: Low Voltage Programming Enable bit

1 = RB3/PGM pin has PGM function, low voltage programming enabled

0 = RB3 pin is digital I/O, HV on MCLR must be used for programming

And this is how the device enters LVP mode as per PICmirco Device Programming page 5:

When PGC and PGD pins are held to logic low at the same time as VDD is applied to both PGM and MCLR, the microcontroller enters Programming mode.

So I unintentionally set the LVP and floated PGC, PGD and PGM before I get to know what LVP is. Because LVP is on and PGC, PGC, PGM are all floating, after I implemented reset which solved the resetting problem but also brought MCLR pin to VDD, the device would go into the Low-voltage programming mode instead of running the code.

related question:

PIC circuit won't stay powered

Seemingly unstable basic PIC18F2550 circuit

Is it really a bad idea to leave an MCU input pin floating?