fj604 34 Posted April 8, 2012 Share Posted April 8, 2012 This rudimentary debouncing code seems to work but the whole idea does not seem to be good - a loop inside ISR. Comments? #define DEBOUNCE_CYCLES 200 #define S2 BIT3 volatile uint8_t s2 = 0; #pragma vector=PORT1_VECTOR __interrupt void Port_1(void) { uint16_t s=0, t; if (P1IFG & S2) { if (!s2) { for (t=0; t if (! (P1IN & S2)) s++; if (s > DEBOUNCE_CYCLES / 2) s2 = 1; // set s2 flag } } P1IFG &= ~S2; // clear interrupt bit } _low_power_mode_off_on_exit(); } Quote Link to post Share on other sites
oPossum 1,083 Posted April 8, 2012 Share Posted April 8, 2012 Use a timer interrupt for debounce. volatile unsigned debounce = 0; volatile unsigned switch_on = 0; #pragma vector = TIMER0_A0_VECTOR __interrupt void Timer0_A0 (void) { // Debounce and check if switch state has changed if(switch_on != (0 != ((P1IN & BIT3) ? (debounce ? --debounce : 0) : (debounce = 25)))) { // Update switch state and test direction of transition if(switch_on = !switch_on) { // Switch has closed } else { // Switch has opened } } } fj604 1 Quote Link to post Share on other sites
rockets4kids 204 Posted April 8, 2012 Share Posted April 8, 2012 Jack Ganssle has a *great* article on debouncing, both hardware and software: http://www.eng.utah.edu/~cs5780/debouncing.pdf Definitely worth reading even if you already have a working debounce routine. oPossum, V0JT4, fj604 and 1 other 4 Quote Link to post Share on other sites
RobG 1,892 Posted April 8, 2012 Share Posted April 8, 2012 You can also use watchdog timer #pragma vector=PORT1_VECTOR __interrupt void PORT1_ISR(void) { P1IE &= ~S2; // disable interrupts on S2 P1IFG &= ~S2; // clear S2 flag WDTCTL = WDT_MDLY_32; // start WDT, interrupt after 32ms (depending on your clock) IFG1 &= ~WDTIFG; // clear WDT flag IE1 |= WDTIE; // enable WDT interrupt // do whatever you need to do with S2 switch2 = P1IN & S2; } #pragma vector=WDT_VECTOR __interrupt void WDT_ISR(void) { IE1 &= ~WDTIE; // disable WDT interrupt IFG1 &= ~WDTIFG; // clear flag WDTCTL = WDTPW + WDTHOLD; // hold WDT P1IE |= S2; // enable interrupts on S2 } Simbo 1 Quote Link to post Share on other sites
rockets4kids 204 Posted April 8, 2012 Share Posted April 8, 2012 You can also use watchdog timer Almost none of my MSP430 circuits use the WDT (as an actual watchdog) or the XTAL, so one of the first things I do in just about all projects is disable the XTAL to use P2.6 and P2.7 as GPIO and then use the VLO to drive the WDT timer as a low-frequency interrupt source -- perfect for debouncing switches. Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.