MCU Examples.com
PIC Microcontroller Project Examples, free source codes and resources collection.


 

Using Push Buttons with PIC microcontrollers and Microchip MPLAB C18 example

Switch Debouncing

Introduction

Push buttons are cheap mechanical devices. When pushed they either make connection between two terminals or break connection between two terminals and when released, comes to original stage. Buttons which make connections between two terminals when pressed are called Push-ON switches and Buttons which breaks connection between two terminals are called push-OFF switches. Fig. 1.a and Fig. 1.b shows electrical symbols of push-ON and push-OFF type switches. Usually common PCB mounted push buttons has four pins (two for each terminal) to give them mechanical stability.

 


        Fig.1.a Push-ON switch


        Fig.1.b Push-OFF switch

 

Connecting push buttons to microcontroller.

There are two ways to connect push button to microcontroller.

1. Pull-UP

2. Pull-DOWN

When push-ON switch connected in pull-down method as in fig.2, microcontroller pin is connected to ground level trough resistor (Logic ‘0’) before switch is pressed. When switch pressed, microcontroller pin is connected to Vcc (Logic ‘1’). When switch is released logic level goes back to Logic ‘0’.

Fig.2 Push button connected as Pull-Down

 

When push-ON switch connected in pull-up method as in fig 3, microcontroller pin is connected to Vcc through resistor (logic ‘1’) before switch is pressed. When switch pressed, microcontroller pin is connected to Ground (Logic ‘0’). When switch is released logic level goes back to Logic ‘1’.

Fig.3 Push button connected as Pull-UP

 

Switch De-bouncing.

Operation of push button switch is simple; it either makes connection or breaks connection between its two terminals. But wait, there is problem. When switch is pressed there is short period of time where oscillation occurs. Oscillation is random and usually less than 10mS for general PCB mounted push button switches known as micro switches. This problem occurs because mechanical contacts of switchs are not perfect and nature of electricity. Different speed of pushing switch is also affects this problem. This phenomenon is called switch de-bouncing.


If we ignore this de-bouncing when developing program for microcontroller, program may behave in unexpected way or, single button press may produce more than one output pulse. To overcome this iissue we introduce small delay in our program. For example, when we detect switch press (logic change, say 0 to 1) in program, we wait small time (usually about 10mS) and again check status of switch, now if we encounter logic 1 again this means logic status of switch is changed from 0 to 1, which is called switch pressed.  Above figures 2 and 3 shows timing diagrams of switch pressing. Note the time periods t1 to t2, t3 to t4 are bouncing. This is what you see if you examine switch press in oscilloscope.


This type delay method of de-bouncing has some disadvantages. Mainly the delay time of 10mS or so iis idling time for MCU and for some applications this time is too much and unacceptable.


Much better way to do debouching is using interrupts. For example we use 10mS timer interrupt which will branch our program to switch scan routine where we will quickly scan status of all of our switches and record them in array or variables. Then after another 10uS same thing will happen. The idea here is simple. For every 10ms time, each push button state will be checked and compared to the previous states recorded. This will uncover rising and falling edges of signal. If there is no change compared to previous state of one switch, it is obvious, that switch is not pressed (or not changed) its status. In case of change from 0 to 1, rising edge detected and change from 1 to 0, falling edge detected. If next 3 or 4 checks do not detect any change in new logic state, we are certain that switch is pressed (or released).

Following example shows simple circuit which has two push button switches and when pressed program will turn on two LEDs respectively.

 

Source code for Using Push Buttons with PIC18F2520 and Microchip MPLAB C18 with switch debouncing. You can download complete MPLAB project here.

//////////////////////////////////////////////////////////
// Designed by www.MCUExamples.com
// rasika0612@gmail.com
//////////////////////////////////////////////////////////

#include <p18f2520.h>

#pragma config OSC    = XT  // 4MHz Crystal, (XT oscillator)
#pragma config PBADEN = OFF // PORTB<4:0> pins are configured as digital I/O on Reset)


void delay_ms(unsigned int duration);
unsigned char is_sw1_pressed(void);
unsigned char is_sw2_pressed(void);


void main()
{
   TRISCbits.TRISC0=0; // Set PortC bit 0 as output, LED1 is connected to thi pin
   TRISCbits.TRISC1=0; // Set PortC bit 0 as output, LED2 is connected to thi pin
    
   LATCbits.LATC0=0; // turn off LED1
   LATCbits.LATC1=0; // turn off LED2

   TRISBbits.TRISB3=1; // configure SW1 pin as input
   TRISBbits.TRISB4=1; // configure SW2 pin as input
    
    while(1)
    {
      if(is_sw1_pressed()==1)    // is key 1 pressed
      {                        // yes
         LATCbits.LATC0=1;     // turn ON LED1    
        }
        else
        {                        //no
            LATCbits.LATC0=0;    //turn off LED1
        }

        if(is_sw2_pressed()==1)    // is key 2 pressed
        {                        // yes
            LATCbits.LATC1=1;     // turn ON LED2    
        }
        else
        {                        //no
            LATCbits.LATC1=0;    //turn off LED2
        }
    }
}

/////////////////////////////////////////////////////////////////////////////////////////
//     this is delay routine
//     input: required Delay duration in mili Seconds
//    output: none
/////////////////////////////////////////////////////////////////////////////////////////

void delay_ms(unsigned int duration) // delay in miliseconds for 4.0MHZ crystal
{
    unsigned int i;
    for(;duration!=0;duration--)
    {
        for(i=0;i<=50;i++)
        {
            _asm
                nop
                nop
                nop
            _endasm
        }
        _asm
            nop
            nop
        _endasm
    }
}


/////////////////////////////////////////////////////////////////////////////////////////
//this routine is to check key1 pressings.
//input: none 
//output: 0 if switch is not pressed. 1 if switch is pressed. 
/////////////////////////////////////////////////////////////////////////////////////////
unsigned char is_sw1_pressed(void)
{
    if (PORTBbits.RB3==0)        // is SW1 pressed?
    {                            //yes
        delay_ms(10);            // wait 10mS for debounce.
        if (LATBbits.LATB3==0)    // is SW1 still has pressed status after 10mS delay?
        {                        // yes, we have key press
            return 1;
        }
    }
    return 0;// if key is not pressed, return 0
}

/////////////////////////////////////////////////////////////////////////////////////////
//this routine is to check key2 pressings.
//input: none 
//output: 0 if switch is not pressed. 1 if switch is pressed. 
/////////////////////////////////////////////////////////////////////////////////////////
unsigned char is_sw2_pressed(void)
{
    if (LATBbits.LATB4==0)        // is SW1 pressed?
    {                            //yes
        delay_ms(10);            // wait 10mS for debounce.
        if (LATBbits.LATB4==0)    // is SW1 still has pressed status after 10mS delay?
        {                        // yes, we have key press
            return 1;
        }
    }
    return 0;// if key is not pressed, return 0
}





 

Custom Search