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.

Start a timer with an button interrupt (MSP432)

Hy guys,

i want to realize a little project which deals with debouncing the button.

For this I want to use 2 interrupts (port and timer).

I don't know if my code is to complicated for my application, but I'm really interested in your solutions.

//*****************************************************************************
//
// MSP432 main.c template - Empty main
//
//****************************************************************************

#include "msp.h"



void main(void)
{
    
    WDTCTL = WDTPW | WDTHOLD;           // Stop watchdog timer



    P1DIR|=BIT0;
    P1OUT&=~BIT1;


    P1IE|=BIT1;
    P1IES|=BIT1;
   // P1REN|=BIT1;


    __enable_interrupt();



    NVIC_ISER1 = 1 << ((INT_PORT1 - 16) & 31);
    NVIC_ISER0 = 1 << ((INT_TA0_0 - 16) & 31);



   

}

void Port1_IsrHandler(void)
{

        P1OUT^=BIT0;
        P1IFG&=~BIT1;
        P1IES^=BIT1;
        TA0CCTL0 = CCIE;                          // TACCR0 interrupt enabled
        TA0CTL = TASSEL_2 | MC_1;    // SMCLK, continuous mode
        TA0CCR0=1500;



}



void TA0_IsrHandler(void)
{


    P1OUT ^= BIT0;
    TA0CCTL0 &= CCIE;

}

thank for your help.


Chris

  • I have to admit that I am struggling to find place where actual button debounce happens in your code.
  • ok i wanted to do that with the timer interrupt, but i think my port interrupt hasn't called.
    I tried it a few minutes before with a easier programm ( only button interrupt to toggle the led) and it failed.
    what would you suggest to do?
  • Don't use port IRQ but polling from timer/tick ISR running at 100 to 1000Hz.
  • I checked my solution with a timer interrupt and the realization with a timer interrupt is easier to do.

    Now i have this source code for the debouncing of the button:



    volatile int counter =0;

    void main()
    {

    ..... //definition of timer, input and output

    while (1)
    {

    if ((counter==0) & (P1IN & BIT1))
    {
    P1OUT^=BIT0;
    }
    else if (counter ==5)
    {
    P1OUT^=BIT0;
    }

    }

    timer interrupt()
    {
    if(P1IN & BIT1)
    counter++;
    }

    What do you think about this?
  • There are button debonunce surce code all over internet. Why are you trying to invent The Wheel? ;)

    Code for "LED on" while button pressed (wrote from scratch, could be buggy):

    volatile unsigned char button_pressed, button_debounce_counter;
    
    while (1) {
      if (button_pressed) {
        LED_on();
      } else {
        LED_off();
      }
      sleep_till_next_ISR();
    }
    
    timer_ISR() {
      if ( !(BUTTON_INPORT & BUTTON_PIN) ) { // logical "0" when button pressed, "1" when released
        if (button_debounce_counter > DEBOUCE_TRESHOLD)  // set treshold count to be equal ~ 50..100 ms
          button_pressed = 1;
        else
          button_debounce_counter++;
      } else {
        button_pressed = 0;
      }
    }

  • Ilmars said:
    Don't use port IRQ but polling from timer/tick ISR running at 100 to 1000Hz.

    This comes from my post here.

    But as I said, I do prefer the timer method without interrupts as well. An interrupt for a button is a little bit exaggerated.

  • new is always better ;)

    were is the DEBOUCE_TRESHOLD defined and which value is defined?
  • This threshold depends on your individual timer settings. If your timer invokes an interrupt every 1ms and you want a debounce time of 10ms, then define it as 10. For 500µs timer interval and 50ms debounce time, define it as 100.

  • I changed the source code with your suggestion:

    //*****************************************************************************
    //
    // MSP432 main.c template - Empty main
    //
    //****************************************************************************

    #include "msp.h"

    volatile unsigned char button_pressed, button_debounce_counter;

    void main(void)
    {

    WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer

    P1DIR|=BIT0;
    P1OUT|=BIT1;
    //P1REN|=BIT1;

    P1OUT=0x00;

    TA0CCTL0=CCIE;
    TA0CTL = TASSEL_2 | MC_1;
    TA0CCR0=320;

    __enable_interrupt();

    NVIC_ISER0 = 1<<((INT_TA0_0 - 16)& 31);

    while(1)
    {
    if (button_pressed) {
    P1OUT|=BIT0;
    } else {
    P1OUT^=BIT0;
    }

    }

    }



    void TA0_0_IsrHandler(void)
    {
    if (!(P1IN & BIT1) ) { // logical "0" when button pressed, "1" when released
    if (button_debounce_counter > 10) // set treshold count to be equal ~ 50..100 ms
    button_pressed = 1;
    else
    button_debounce_counter++;
    } else {
    button_pressed = 0;
    }
    }

    but it doesn't work at all.
  • Why did you comment out the pull-up resistor?

    And you have to reset your button_debounce_counter somewhere.

  • i commented out the pull-up for a test.
    Now i initialized the button with 0 at the beginning and int the 2nd else in the timer ISR.
  • XOR is "toggle" operation. to reset LED port bit you shall use AND:
    P1OUT &= ~BIT0;

    Otherwise while button is not pressed, your LED will glow at 50% brightness which could be so bright that you think it is on.
  • I changed this already to P1OUT=0x00 and P1OUT=0xFF.
    Now im troubleshooting with the Timer_ISR.
  • Now i have problems with the Timer_ISR.
    The ISR was called but the comparison of the value didn't work and I don't know why.

    This is my actual code:

    //*****************************************************************************
    //
    // MSP432 main.c template - Empty main
    //
    //****************************************************************************

    #include "msp.h"

    volatile unsigned int button_pressed = 0;
    volatile unsigned int button_debounce_counter=0;

    void main(void)
    {

    WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer

    P1DIR|=BIT0;
    P1OUT|=BIT1;
    P1REN|=BIT1;

    P1OUT=0x00;

    button_debounce_counter=0;


    TA0CCTL0=CCIE;
    TA0CTL = TASSEL_2 | MC_1;
    TA0CCR0=10000;

    __enable_interrupt();



    NVIC_ISER0 = 1<<((INT_TA0_0 - 16)& 31);

    while(1)
    {
    if (button_pressed)
    {
    P1OUT = 0xFF;



    } else
    {
    P1OUT= 0x00;


    }



    }

    }



    void TA0_0_IsrHandler(void)
    {


    //button_pressed = 1;

    if ((P1IN & BIT1) )
    { // logical "0" when button pressed, "1" when released
    if (button_debounce_counter > 10) // set treshold count to be equal ~ 50..100 ms
    {button_pressed = 1 ;
    P1OUT=0xFF;
    }

    else
    button_debounce_counter++;
    }
    else
    {
    button_debounce_counter=0;
    button_pressed=0;
    P1OUT=0x00;
    }



    }
  • Christoph Marko said:
    The ISR was called but the comparison of the value didn't work and I don't know why.

    Hi Christoph!

    Which comparison are you talking about?

    Dennis

  • Hi Dennis,

    I meant the comparison in the timer ISR.
    Could it be that the P1DIR and P1OUT was false assigned?

    Chris
  • There is a major fault in your code - you inittialize your port 1 here:

    P1DIR |= BIT0;
    P1OUT |= BIT1;
    P1REN |= BIT1;

    This sets P1.0 to output direction, sets P1.1 high and enables the resistor for P1.1, which results in a pull-up. Correct so far, but your next line

    P1OUT = 0x00;

    overrides the previous made setting and sets the resistor to pull-down. I guess you simply wanted the LED at P1.0 to be off, right? You have to use bitwise operations. To only set P1.0 low, write

    P1OUT &= ~BIT0;

    Or for high write

    P1OUT |= BIT0;

    This is also wrong here:

    if( button_pressed )
    {
      P1OUT = 0xFF;
    }
    else
    {
      P1OUT = 0x00;
    }

    Again, you also change the setting of the resistor. Another time in your ISR:

    if( P1IN & BIT1 )
    {
      if( button_debounce_counter > 10 )
      {
        button_pressed = 1 ;
        P1OUT = 0xFF;                  // <- HERE
      }
      else
      {
        button_debounce_counter++;
      }
    }
    else
    {
      button_debounce_counter = 0;
      button_pressed = 0;
      P1OUT = 0x00;                    // <- HERE
    }

    Dennis

    P.S.: Please use the syntax highlighter for inserting code which is available in rich formatting mode that appears on the lower right when replying.

  • Thank you dennis, i changed it like you suggested.
    I commented out all the code in the timer ISR and set button_pressed to 1.
    I checked it in the debug mode that the variable got 1, but back in the while loop the LED didn't light.
    The crazy thing is when I set the P1OUT like you suggested, the LED lights.
  • I just saw another thing:

    if( P1IN & BIT1 )
    {
      ...
    }

    This checks if the input pin is high, so NOT pressed. You want

    if( !(P1IN & BIT1) )
    {
      ...
    }

    Dennis

  • Hi
    i am Beginner for Embedded. Recently i purchased MSP432 launchpad. i am able to blink on board LED's.
    can you help me in how to configure timers, what are the steps to be followed.
  • Your problem/question does not relate so much to particular thread. You are advised to start new thread
  • I found my problem already, but thank you for your advice. ;)

**Attention** This is a public forum