Electrical – Simple number counter – PIC16F877A microcontroller problem

countermicrocontrollermplab

enter image description hereI am trying to make a simple counter using pic16f877a. I want to count each time a push button is pressed, that is taking one press as one count, regardless of how long the button is pressed.

The software I am using are MPLAB X IDE and XC8 compiler. I use Pickit 3.5. I use an indicator LED to see whether the code is working.

The thing is, I have barely achieved what I needed, but the code seems unstable. It works sometimes but not in others. For example, let say the code worked now and LED blinked correctly when one of two connected buttons pushed. Then if I "make" and "download" the program again without any edits to the code in MPLAB X IDE, the LED won't blink. While writing this I tested several times just by making and downloading using MPLAB IDE, without changing anything hardware or code, and then it worked. The only thing that was changed in those situations was TIME. I suspect this has something to do with resetting of the PIC although I have no idea. Never worked on 2 consecutive "make and download"s.

Code:

#define _XTAL_FREQ 20000000
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <pic16f877a.h>
// CONFIG
#pragma config FOSC = HS    
#pragma config WDTE = OFF    
#pragma config PWRTE = OFF   
#pragma config BOREN = OFF   
#pragma config LVP = OFF    
#pragma config CPD = OFF  
#pragma config WRT = OFF        
#pragma config CP = OFF

void main(void) {
    TRISB=0;//LED connected to RB0
    TRISD=1;//two push buttons connected to RD0(buttonRight) and RD1(buttonLeft)

    while(1)
    {
        if (PORTDbits.RD0==0)//if buttonRight is pressed,
        {
            __delay_ms(5);//debouncing.
            if (PORTDbits.RD0==0)//if buttonRight is still pressed,
            {
                PORTBbits.RB0=1;
                __delay_ms(500);
                PORTBbits.RB0=0;
                __delay_ms(500);

                /*to take as one press no matter for how long it is pressed.*/
                while(PORTDbits.RD0==0);
            }
        }

        else if (PORTDbits.RD1==0)//if buttonLeft is pressed,
        {
            __delay_ms(5);//debouncing.
            if (PORTDbits.RD1==0)//if buttonLeft is still pressed,
            {
                PORTBbits.RB0=1;
                __delay_ms(100);
                PORTBbits.RB0=0;
                __delay_ms(100);

                /*to take as one press no matter for how long it is pressed.*/
                while(PORTDbits.RD1==0);
            }
        }
    }
}

Best Answer

Port D0 and Port D1 should be an input. If you write:

TRISD = 1;

you only make PortD.1 an input.

Maybe ist clearer if you think in binary:

TRISD = 1:

is simular to:

TRISD = 0b00000001;

which writes 1 only to Port D.0 and put all other Pin of D to 0. So write:

TRISD = 0b00000011;