This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DEBOUNCING THE SWITCH S2(P1.3) IN MSP430

HAI

i am using p1.3 as a switch so that when i push it..it generates the interrupt and in the port ISR..i m sending a character by UART...i m getting the output...but sometimes the character is transmitted twice or thrice...

i am using the below code..what should be done to avoid this problem..need help from you all..

void main(void) {
WDTCTL = WDTPW + WDTHOLD;

BCSCTL1 = CALBC1_1MHZ;
DCOCTL = CALDCO_1MHZ;
P1SEL = BIT1 + BIT2 ;
P1SEL2 = BIT1 + BIT2 ;

.

.

.

.//UART initialisation

P1SEL &= ~0x08;

P1DIR &= ~0x08;

P1REN |= 0x08;

P1IE |= 0x08;

P1IFG &= ~0x08;

_BIS_SR(LPM0_bits+GIE);


}

#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void) {


P1IFG &= ~0x08;


while (!(IFG2 & UCA0TXIFG));
UCA0TXBUF = 'a';

}

thanks in advance

senthil.

  • What I'm about to suggest is bad design, but since you have a busy-wait while loop in your ISR, I guess it doesn't matter.

    Try just clearing the interrupt flag at the END of the ISR.  That way, you are basically preventing any new/false key presses during the time the previous 'a' character is being transmitted.  That is, move your P1IFG &= ~0x08 after the last ISR statement.

    A better way to fix this is to use a timer counter that increments a value every, for example, 100ms.  The ISR would have a static variable set to that value just before sending the 'a' character.  At entry of the ISR, the static variable value and the current time value would be compared, if they are equal then assume the switch is bouncing and don't send the  'a' character.

  • You may want to check out http://www.ganssle.com/debouncing.htm for a comprehensive view of debouncing along with some code.
  • hai quark,

    thanks for your response...i am new to this controller..my doubt is like what value can i set the for the timer counter..and how the static variable value is decided...can you just explain me the flow of the code..so that i can understand it..


    thanks & regards,
    senthil
  • hai todd,
    the link shows like the content is missing..can you send me the correct link...thanks for your response

    thanks & regards,
    senthil
  • The link works fine for me

    http://www.ganssle.com/debouncing.htm

    Bouncing buttons is a problem everyone is facing sometime when connecting them to the microcontroller :-) Of course, having while loops in ISRs isn't very good at all, but it seems as if you are just beginning and testing out some of the functionality. Clearing the flag at the end of the ISR will give the button some time to debounce, but this is only µs.

    Have a look what happens for the first interrupt: The buttons first contact enters the ISR and the flag is cleared immediately. Your button is still bouncing...the flag is set again. Your TXIFG is set because there haven't been a transmission yet so the buffer is empty. Now you put your 'a' into the TX-buffer which clears TXIFG. End of ISR, but the flag is still set, so there will be another interrupt again. This again is handled in some µs. Because you just sent the first byte the TXIFG is set again because the USCI has moved the byte to the shift-register capable of fetching a next byte while still transmitting your first one. The while loop won't give you time because TXIFG is set again. Now you are copying the second byte to the TX-buffer which clears TXIFG again. Elapsed time...still some more µs, but buttons can bounce some ms. So the IFG is set again. Now the while loop comes into place because the first byte is still in transmission, the second byte is in the TX-buffer and TXIFG is cleared, not able to receive another byte so the loop is entered and entered again until the first byte is transmitted and the second is moved to the shift-register. Now TXIFG is set again and the third byte is moved into the TXBUF while the second will be transmitted.

    This now could have been enugh time for the button to debounce, but you get three transmissions for one button press.

    What you could do: Work completely without the interrupt:

    void main( void )
    {
      ...
    
      if( button_pressed )
      {
        TXBUF = byte;
        delay(); // For some ms to debounce
        while( button_pressed ); // Wait until released again
      }
    }

    Or you could do the same in the ISR, clearing the flag at the end. Or set a flag in the ISR and handle the rest in your main program. The best way is to set up a timer that causes an interrupt every 10ms, for example, checking the buttons and set a flag if the button has a) changed and b) is still changed after the second 10ms interval.


    Dennis

  • hai dennis,
    thanks for your response...now i clearly understand what the thing is happening behind my program...i saw in a link below stating that the maximum debounce time is 32ms i.e)humans cannot press faster than this...

    https://bennthomsen.wordpress.com/engineering-toolbox/ti-msp430-launchpad/using-the-switches/

    so i tried to modify the code...i wanna know whether it is efficient with that code..i use the code below.

    void main(void)
    ....
    ..
    ...
    ...

    while(1)
    {
    timercount = 0;
    P1IE &= ~0X08;
    if(!(P1IN & BIT3))
    {
    timercount++;
    }
    P1IE |= 0x08;
    P1IFG &= ~0x08;
    }

    }

    #pragma vector=PORT1_VECTOR
    __interrupt void Port_1(void) {

    if(timercount < 32000)
    {
    while (!(IFG2 & UCA0TXIFG));
    //transmit the character
    P1IFG &= ~0x08;
    }



    will it be fine...thanks again for your detailed response...it was helpfull..


    regards,
    senthil
  • Sorry, but that doesn't make sense at all.

    Just have a look at your while-loop:

    while(1)
    {
      timercount = 0;
    
      P1IE &= ~0X08;
    
      if(!(P1IN & BIT3))
      {
        timercount++;
      }
    
      P1IE |= 0x08;
      P1IFG &= ~0x08;
    }

    Each time the program runs to the start of the while(1)-loop it resets the timercount. This variable will never be more than 1 because it is reset the next time your program comes to the begin of the loop again. That's one thing, but not the only one that isn't useful. Think about what you want to do first. Go through your code and try to imagine what happens when.

    Dennis

  • thanks for your response dennis...i will think on what you have said..will get back to you..once i get a idea of what i gonna do..thanks again..

    regards,
    senthil
  • Responding to your earlier comment, the Debouncing article can be found on www.ganssle.com and then doing a "Search" with "debouncing" as the topic. The particular article I was pointing to was the second on the "search" list.

**Attention** This is a public forum