Interfacing button with led to PIC16f877a

Thread Starter

bobparihar

Joined Jul 31, 2014
93
iam new to PIC micro controller
i was doing an interfacing of button and led to the micro controller
objective is simple on pressing the button led should glow.. on releasing the button led should off

following is the program in Mikro C compiler

void main() {

TRISC.F0=0; // for making pin 0 of PORTC as output, for led

TRISC.F1=1; // for making pin 1 of PORTC as input for button
while(1)
{
PORTC.F0=0;
while(PORTC.F1==0)
{
PORTC.F0=1;
}
}
}



the problem here is led glows independent on the button... its not working please correct me
the same logic does work for 8051... but not here... why?
 

MrChips

Joined Oct 2, 2009
34,812
You cannot assume that an input pin with nothing connected has a defined state.
Some MCU has internal pull-up/pull-down resistors built-in.
In your case, connect a pull-up resistor (1k to 10kΩ) from pin-16 to VDD.
 

Thread Starter

bobparihar

Joined Jul 31, 2014
93
You cannot assume that an input pin with nothing connected has a defined state.
Some MCU has internal pull-up/pull-down resistors built-in.
In your case, connect a pull-up resistor (1k to 10kΩ) from pin-16 to VDD.
thanks for help sir, but will you please elaborate?
 

vinnnie

Joined Jan 21, 2013
13
And I find some errors in that code, I mean:
Why you put a while in that case? With this code the led will glow only once and then the PIC program will end, I recommend to use some interrupt in this case.
 

Thread Starter

bobparihar

Joined Jul 31, 2014
93
And I find some errors in that code, I mean:
Why you put a while in that case? With this code the led will glow only once and then the PIC program will end, I recommend to use some interrupt in this case.
this code is just a demo.. i just want o clear my concepts on single pin accessing of pic16f877a mcu
and i put a while because i want to poll the button status continuously on that pin
 

ErnieM

Joined Apr 24, 2011
8,415
While it may be hard to read due to bad formatting the code should work.
Code:
void main() {

    TRISC.F0=0; // for making pin 0 of PORTC as output, for led

    TRISC.F1=1; // for making pin 1 of PORTC as input for button
    while(1)
    {
        PORTC.F0=0;
        while(PORTC.F1==0)
        {
        PORTC.F0=1;
        }
    }
}
So the port bit is turned off, then turned on if the button is low, then the loop runs again.

Not the most elegant way of doing things but it works.
 

tshuck

Joined Oct 18, 2012
3,534
thanks for help sir, but will you please elaborate?
As is, your diagram only has a known state when the button is pressed - it's connected to common, but what is the voltage on the input if the button is not pressed?

You've left it floating in an undefined state (the simulator might even call this node 0 to be able to account for it).

Add a resistor (10k is typical) from this input pin to Vcc, called a pullup resistor as it pulls the voltage up to Vcc, or, logic '1'. When the button is pressed, the input is connected directly to common and is at logic '0'.

This way, you ensure your input is always at a known state, depending on the button state.
 

Thread Starter

bobparihar

Joined Jul 31, 2014
93
While it may be hard to read due to bad formatting the code should work.
Code:
void main() {

    TRISC.F0=0; // for making pin 0 of PORTC as output, for led

    TRISC.F1=1; // for making pin 1 of PORTC as input for button
    while(1)
    {
        PORTC.F0=0;
        while(PORTC.F1==0)
        {
        PORTC.F0=1;
        }
    }
}
So the port bit is turned off, then turned on if the button is low, then the loop runs again.

Not the most elegant way of doing things but it works.
thanks for replying, what u think is the good way(code) to do this task..?
 

ErnieM

Joined Apr 24, 2011
8,415
First your code will work just fine (assuming there is nothing else on PORTC.F1 which I did not check), it is just not the traditional way these things are handled as you have two interwoven loops. However, that scheme is used as is in assembly programs where every instruction is closely scrutinized to see if it is really necessary.

For now I would not worry about what code to write, but here is an example of a "more traditional" way:
Code:
void main() {
    TRISC.F0=0; // for making pin 0 of PORTC as output, for led
    TRISC.F1=1; // for making pin 1 of PORTC as input for button
    while(1)
    {
    if (PORTC.F1==0)
        {
            PORTC.F0=1;
        }
    else
    {
            PORTC.F0=0;
    }
    }
}
This leaves the loop "balanced" (equal number of statements either path) and makes the intent of your code clear.

What is more importaint is to start using a consistant "coding standard" where indents are used to seperate loops and other blocks of code so their meaning is clear to a human reading it.

That human is usually you so be good to yourself. ;-)
 

MCU88

Joined Mar 12, 2015
358
Not the most elegant way of doing things but it works.
Personally I would do this:

Code:
#define button PORTA.F0    // Assign pin bit 0 of porta to an button
#define led001 PORTA.F1    // Assign pin bit 1 of porta to an led

void main()  // Program entry point
{
   while(1)  // Infinite loop
   {
      led001 = button;   // Copy logical state of button to led pin
   }
}
 
Top