PIC Switch Debouncing

Discussion in 'Embedded Systems and Microcontrollers' started by nelsonys, Apr 24, 2011.

  1. nelsonys

    Thread Starter New Member

    Apr 6, 2011
    I'm trying to use the code provided by Microchip to debounce the switch, but I couldn't really understand the code itself:

    // This lesson shows one method to software debounce a switch input.
    // The switch is sampled once every millisecond and must be low for
    // 5 samples in a row to register a "press". Each press rotates
    // the LEDs on PORTD.

    #include "p18f45k20.h"
    #include "delays.h"
    #include "04 Switch Input.h" // header file

    /** V A R I A B L E S *************************************************/
    #pragma udata // declare statically allocated uinitialized variables
    unsigned char LED_Display; // 8-bit variable

    /** D E C L A R A T I O N S *******************************************/
    #pragma code // declare executable instructions

    void main (void)
    unsigned char Switch_Count = 0;

    LED_Display = 1; // initialize

    TRISD = 0b00000000; // PORTD bits 7:0 are all outputs (0)
    INTCON2bits.RBPU = 0; // enable PORTB internal pullups
    WPUBbits.WPUB0 = 1; // enable pull up on RB0
    ANSELH = 0x00; // AN8-12 are digital inputs (AN12 on RB0)
    TRISBbits.TRISB0 = 1; // PORTB bit 0 (connected to switch) is input (1)

    while (1)
    LATD = LED_Display; // output LED_Display value to PORTD LEDs

    LED_Display <<= 1; // rotate display by 1

    if (LED_Display == 0)
    LED_Display = 1; // rotated bit out, so set bit 0

    while (Switch_Pin != 1);// wait for switch to be released

    Switch_Count = 5;
    { // monitor switch input for 5 lows in a row to debounce
    if (Switch_Pin == 0)
    { // pressed state detected
    Switch_Count = 0;
    Delay10TCYx(25); // delay 250 cycles or 1ms.
    } while (Switch_Count < DetectsInARow);


    1. I don't understand what do the #pragma udata and #pragma code work for.
    2. For the first while(Switch_Pin != 1), could it be replaced by while(Switch_Pin == 0)?
    3. I wonder why the Switch_Count=5 is declared as this way, because if it is to work as the comment stated above(sample 5 consecutive low), I thought it should be Switch_Count=0, because from my understanding of the code, it will immediately loop out of the while(Switch_Count < DetectsInARow) once it detected a pressed state by incrementing Switch_Count to 6, and if the user is fast enough to press the switch before the code loads tilll Switch_Count=5, hehehe...

  2. nelsonys

    Thread Starter New Member

    Apr 6, 2011
    Sorry, I would also like to know how does the code work to rotate the LED. Thanks...
  3. MikeInRI

    New Member

    Apr 6, 2011
    Check the C18 User's Guide for this.

    Strictly speaking, these are not necessarily the same. i.e. if the value of Switch_Pin were other than 1 or 0. In your project, it may make no difference depending on the definition of Switch_Pin... which I do not see.

    Try Switch_Count--;

    This...LED_Display <<= 1; .... code says to shift the (binary representation) value of LED_Display left one bit. So, for 8-bit, 0b00000001 left shifted one bit becomes 0b00000010.
  4. nelsonys

    Thread Starter New Member

    Apr 6, 2011

    Regarding Q1, I have read #pragma DIRECTIVE stated in C18 User's Guide.
    for #pragma code, it is to tell the MPLAB 18 to compile the C language code following this directive into the "code" section of program memory. I thought even without this declaration, the code will also be programmed into the code section of the ROM?

    and for #pragma udata, the unitialized variables defined after this declaration will use the General Purpose Registers for storage. Firstly, I do not really understand what is "uninitialized" here means. Secondly, what is the main purpose to store "unsigned char LED_Display" variable here into General Purpose Register?