Quantcast
Channel: MSP low-power microcontroller forum - Recent Threads
Viewing all articles
Browse latest Browse all 21936

MSP430G2553: inconsistent behavior re setting up push button interrupt with software debounce

$
0
0

Part Number:MSP430G2553

Hi. I have a MSP430G2553 that I am using to develop a system to select from one of four options using leds as indicators of which option is currently selectable and a push button to make the selection. The way I have the code configured, it works as expected something close to 80% of the time. My question is can anyone see how I have incorrectly coded this given that the trace on an oscilloscope shows observed button bounce is shorter than software debounce time?

In the code, I use Timer1_A1 in continuous mode to cycle between 4 leds with a delay. I have used a software debounce (from bennthomsen.wordpress.com/engineering-toolbox/ti-msp430-launchpad/using-the-switches/) that uses the watchdog timer set to create a 32ms delay (WDT_MDLY_32) before re enabling the interrupt on the push button pin. The interrupt is set to trigger on a low-to-high transition and the pin is pulled up so that the button triggers the interrupt on release. I have only observed bounce times on the order of < 200 us on this breadboarded circuit so either I didn't set the button up correctly or I have failed to implement the watchdog software delay correctly.

Thanks for any help that you can provide!

Nick

#include <msp430.h>

#define LED1 BIT4
#define LED2 BIT5
#define LED3 BIT0
#define LED4 BIT1
#define PB1 BIT2

volatile int timerOverflow = 0;
volatile int pushButtonPressed = 0;

void turnOffLeds(void);
/*
 * main.c
 */
int main(void) {
    int selectingLED = 1;
    int ledPosit = 0;
    int myLeds[4] = {LED1, LED2, LED3, LED4};

    WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer
    //set ports as i/o
    P1SEL = 0;
    P1SEL2 = 0;
    P1DIR |= (LED1 + LED2);
	P1OUT &= ~(LED1 + LED2); //turn these off

	P2SEL = 0;
    P2SEL2 = 0;
    P2DIR |= (LED3 + LED4);
	P2OUT &= ~(LED3 + LED4); //turn these off

    //start with this LED ON
    P1OUT = LED1;

    //set up pushbutton
    P2DIR &= ~PB1; // set up as input pin
    P2REN |= PB1; // enable pull up/down resistor
    P2OUT |= PB1; // select pull up
    P2IES &= ~PB1; // enable interrupt to trigger on rising edge
    P2IFG &= ~PB1; // clear interrupt flag
    P2IE |= PB1; // enable interrupts on this pin
	/*
	 * MC_2 continuous up, ID_3 input divide by 8, TASSEL_2 SMCLK, enable interrupt
	 */
	TA1CTL = MC_2 + TASSEL_2 + ID_3 + TAIE;
    __enable_interrupt();
	for(;;)
	{
	    int lpbPressed = pushButtonPressed;
	    if(lpbPressed == 1)
	    {
	        if (selectingLED == 1)
	        {
	            // disable timer interrupt
	            TA1CTL &= ~TAIE;
	            selectingLED = 0;
	        }else{
	            //enable timer interrupt and back to displaying LEDs
	            TA1CTL |= TAIE;
	            selectingLED = 1;
	            //turnOffLeds();
	        }
	        pushButtonPressed = 0;
	        //enable push button interrupt
	        P2IE |= PB1;
	    }
	    if(timerOverflow == 1)
	    {
	        timerOverflow = 0;
	        //turn off all leds
	        turnOffLeds();
	        if (ledPosit < 2) //check for PORT1
	        {
	            P1OUT |= myLeds[ledPosit];
	        }else{ // must be PORT2
	            P2OUT |= myLeds[ledPosit];
	        }
	        if (ledPosit > 2)
	        {
	            ledPosit = 0;
	        }else{
	            ledPosit = ledPosit + 1;
	        }
	    }
	}
	return 0;
}
void turnOffLeds(void)
{
    P1OUT &= ~(LED1 + LED2);
    P2OUT &= ~(LED3 + LED4);
}
#pragma vector = PORT2_VECTOR
__interrupt void PORT2_ISR (void)
{
        P2IFG &= ~PB1; // clear flag
        P2IE &= ~PB1; // disable interrupt
        /*
        WDTCTL = WDT_MDLY_32; // start and set WD timer for btn debounce
        IFG1 &= ~WDTIFG; // clear flag
        IE1 |= WDTIE; // enable WDT interrupt
        */
        pushButtonPressed = 1;
}
#pragma vector = WDT_VECTOR
__interrupt void WDT_ISR(void)
{
    IE1 &= ~WDTIE; // disable WDT
    IFG1 &= ~WDTIFG; // clear flag
    WDTCTL =  WDTPW | WDTHOLD; // stop WD
    //enable push button interrupt
    P2IE |= PB1;
}
#pragma vector = TIMER1_A1_VECTOR
__interrupt void Timer1_A1_ISR (void)
{
    static int timerCounter = 0;
    switch(TA1IV){
    case 10://overflow TA1IFG
    {
        if (timerCounter == 3)
        {
            timerOverflow = 1;
            timerCounter = 0;
        }else{
            timerCounter = timerCounter + 1;
        }
        break;
    }
    default:
        //oops
        break;
    }
}


Viewing all articles
Browse latest Browse all 21936

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>