Jump to content
Sign in to follow this  
boseji

Key Debouncing in MSP430F2013

Recommended Posts

Hello,

 

I am trying to make the shortest Key denounce algorithm for the MSP430F2013.

Listed below is a code:

#include 
unsigned int button1,button2;
#define BTN1    BIT4
#define BTN2    BIT3
.
.
.
void main()
{
.
.
.
//Initialization
 P1OUT |= BTN1+BTN2;               //Btn1,Btn2: P1.4,P1.5 set, else reset
 P1REN |= BTN1+BTN2;               //Btn1,Btn2: P1.4,P1.5 pullup
 P1IE  |= BTN1+BTN2;               //Btn1,Btn2: P1.4,P1.5 interrupt enabled
 P1IES |= BTN1+BTN2;               //Btn1,Btn2: P1.4,P1.5 Hi/lo edge
 P1IFG &= ~(BTN1+BTN2);            //Btn1,Btn2: P1.4,P1.5 IFG cleared
 button1=0;
 button2=0;
.
.
_BIS_SR(GIE);     				// Enable Interrupts
.
.
.
}
// Port 1 interrupt service routine
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{ 
 unsigned char pin;
 pin = P1IN;
 if(!(pin&BTN1))						//Check for Btn1 (P1.4)
 {  	
   ++button1;                          //Button 1 was clicked
 	P1IFG &= ~BTN1;                     // P1.4 IFG cleared
   _BIC_SR_IRQ(LPM4_bits);             //Exit LPM4 mode
 }
 if(!(pin&BTN2))						//Check for Btn2 (P1.3)
 {
   ++button2;                          //Button 2 was clicked
 	P1IFG &=~BTN2;                     	// P1.3 IFG cleared
   _BIC_SR_IRQ(LPM4_bits);             //exit LPM4 mode
 } 
 else
 P1IFG = 0; 	  
}

Problem is that even with this I am getting some spurious button clicks.

Kindly suggest if there is a work arround.

 

Warm Regards,

Boseji

http://m8051.blogspot.com

Share this post


Link to post
Share on other sites

Boseji:

 

First, a disclaimer: I'm new to microcontrollers (but not to programming).

 

I think the reason you're still getting bounce is that this doesn't wait long enough. Once you've checked the button, you clear the interrupt right away. Another interrupt can occur within microseconds (e.g. through bounce).

 

Perhaps if you cleared the interrupt after the action was completed? If the action is something more than a few commands, the processing time could be the delay you need. If not, you may have to introduce a delay of some kind.

 

I have seen someone (NJC?) suggest simply setting a flag and coming out of LPM in the interrupt, then checking for the flag in main(). Although I've never tried it, that sounds reasonable unless your main() is very short (this again relies on processing taking longer than bouncing).

EDIT: As I recall now, the flagging code was to reduce the amount of code in the interrupt, not to debounce. The quest continues.

 

I know I'm going to need to figure this out as well, so keep posting if you come up with a reliable solution!

Share this post


Link to post
Share on other sites

@Doc

Thanks for the shoutout. :-) And you are right, the example I provided was just to reduce the amount of code in the interrupt; I still have yet to provide any debouncing examples. I might in the future in a small post.

 

@Boseji and Doc

Till I write a post up on it, here are a few resources to help you guys get started. It is very hard to program for debouncing without first understanding exactly what is happening. Do not worry too much about the code examples on this site, but definitely read up on what is actually going on when a button bounces.

 

http://www.rentron.com/Myke6.htm

 

Basically once you register your first interrupt you can go about this two ways. For both methods, you start a counter or timer which lasts approximately 15-20ms. For the first method all you need to do is make sure that the button interrupt can not happen during this waiting period, ie. disable the interrupt right away then re-enable it after the delay. A better option in my opinion though is to start the timer right after the first interrupt then once its over, wait inside of a while loop which waits for the button to be released. There are many benefits to using this method.

 

Hope that made sense for you guys, if not, keep asking questions.

Share this post


Link to post
Share on other sites

Hello,

 

Thanks for your Reply I have been able to successfully solve the problem of button de-bounce.

This goes in two phases-

Hardware : I attached the 10nF Caps to the button helps to reduce the chattering.

Software : I fixed up some code with a Delay for De-bounce and checking the bits at proper times. Listed below are the code snippets:

....
#define BTN1    BIT4
#define BTN2    BIT3
....
unsigned int button;
....
void main()
{
......
 P1OUT |= BTN1+BTN2;               // Btn1,Btn2: P1.4,P1.3 set, else reset
 P1REN |= BTN1+BTN2;               // Btn1,Btn2: P1.4,P1.3 pullup
 P1IE  |= BTN1+BTN2;               // Btn1,Btn2: P1.4,P1.3 interrupt enabled
 P1IES |= BTN1+BTN2;               // Btn1,Btn2: P1.4,P1.3 Hi/lo edge
 P1IFG &= ~(BTN1+BTN2);            // Btn1,Btn2: P1.4,P1.3 IFG cleared
......
_BIS_SR(GIE);
......
while(1)
{
......
if(button) //Button Debounce
   {
       P1IE &= ~(BTN1+BTN2); // Disable
       if(button&4)
       {            
           if(!(P1IN&BTN1))//Still the Button is pressed
           {             
               {//50 mS debounce
                   unsigned int i;
                for(i=0;i<6000;i++);                     
               }   
               if(!(P1IN&BTN1))//Still pressed
               button|=1;
           }
           button&=~4;                 //Clear interrupt flag
       }
       if(button&8)
       {
           if(!(P1IN&BTN2))//Still the Button is pressed
           {
               {//50 mS debounce
                   unsigned int i;
                for(i=0;i<6000;i++);                     
               }
               if(!(P1IN&BTN2))//Still pressed
               button|=2;
           }
           button&=~8;                 //Clear interrupt flag
       }
       P1IFG = 0;
       P1IE |= BTN1+BTN2;              // Enable        
   }
......
}
}
.......
// Port 1 interrupt service routine
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{ 
 if(!(P1IN&BTN1))						//Check for Btn1 (P1.4)
 {  	
   button|=4;                          //Button 1 was clicked
 	P1IFG &= ~BTN1;                     // P1.4 IFG cleared                          
   _BIC_SR_IRQ(LPM4_bits);             //Exit LPM4 mode
 }
 if(!(P1IN&BTN2))						//Check for Btn2 (P1.3)
 {
   button|=8;                          //Button 2 was clicked
 	P1IFG &=~BTN2;                     	// P1.3 IFG cleared    
   _BIC_SR_IRQ(LPM4_bits);             //exit LPM4 mode
 } 
 else
 P1IFG = 0; 	  
}

Well this did the job pretty well and now my project Samay1 http://www.43oh.com/2010/08/keeping-time-with-the-msp430/ is fixed. Hope that soon I can publish an article on the tricks that I found in removing this bug.

Thanks to this forum for helping me out.

 

Warm Regards,

Boseji

http://m8051.blogspot.com

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×