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.

MSP430 Interrupt

Hi! I am trying to control servo motor with interrupt but it doesnt work :\ what is my mistake?How can I fix it?


#include <msp430.h>

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

  BCSCTL1   = CALBC1_1MHZ;             // Set DCO range
  DCOCTL    = CALDCO_1MHZ;             // Set DCO step and modulation

  P1DIR     =  0x04;                   // Set P1.2 to output-direction
  P1REN     =  (0x08 | 0x10 | 0x20);   // Enable resistors at P1.3/4/5
  P1OUT     =  (0x08 | 0x10 | 0x20);   // Pull-up resistors at P1.3/4/5
  P1IE  	= (0x08 | 0x10 | 0x20);
  P1IES		= (0x08 | 0x10 | 0x20);
  P1IFG 	= (0x08 | 0x10 | 0x20);
  P1SEL     =  0x04;                   // Set selection register 1 for timer-function



  TA0CCTL1  = OUTMOD_7;                // Reset/set
  TA0CCR0   = 20000;                   // Period
  TA0CCR1   = 1500;                    // Duty-cycle
  TA0CTL    = (TASSEL_2 | MC_1);       // SMCLK, timer in up-mode
  _BIS_SR(GIE);

  while( 1 )                           // Endless-loop (main-program)
  {}

  }
#pragma vector=PORT1_VECTOR
__interrupt void P1_ISR(void)
{
    if( !(P1IFG & 0x08) )               // Button at P1.3 pressed (S2 on LaunchPad)
    {
      TA0CCR1 = 1500;                  // Servo in middle position (1.5ms)
    }
    else if( !(P1IFG & 0x10) )          // Button at P1.4 pressed
    {
      TA0CCR1 = 1000;                  // Servo in minimum position (1.0ms)
    }
    else if( !(P1IFG & 0x20) )          // Button at P1.5 pressed
    {
      TA0CCR1 = 2000;                  // Servo in maximum position (2.0ms)
    }
    P1IFG = (0x08 | 0x10 | 0x20);
}

  • The P1IFG bits are active high.

    You should clear the P1IFG bits with (2 places):
    > P1IFG &= ~(0x08 | 0x10 | 0x20);

    and test them with (3 places):
    > if( (P1IFG & 0x08) )

    Since you set them initially, they're always high so the ISR does nothing.

    Eventually you'll run into trouble with switch bounce, but this particular code (once fixed) will generally work.
  • It works now thank you but how can I prevent debouncing if its happen?
  • You can start a timer inside the button interrupt and re-read the buttons after the timer expired 10 or 20ms later, for example. If the button state is still equal to the point where the interrupt happened, it is definitely pressed and debounced. Or use a timer that reads the buttons every 10ms and check if the state has changed since the last read without the button interrupt.

  • #include <msp430.h>
    
    void main( void )
    {
      WDTCTL    = (WDTPW | WDTHOLD);       // Stop watchdog timer
    
      BCSCTL1   = CALBC1_1MHZ;             // Set DCO range
      DCOCTL    = CALDCO_1MHZ;             // Set DCO step and modulation
    
      P1DIR     =  0x04 + BIT1+ BIT6;                   // Set P1.2 to output-direction//Bit1 = g , Bit6 = f
      P1REN     =  (0x08 | 0x10 | 0x20);   // Enable resistors at P1.3/4/5
      P1OUT     =  (0x08 | 0x10 | 0x20 | BIT1 | BIT6 );   // Pull-up resistors at P1.3/4/5 
      P2DIR     =  (BIT1 | BIT2 | BIT3 | BIT4 | BIT5); //Bit1 = a , Bit2 = d , Bit3 = e , Bit4 = c , Bit5 = b)
      P2OUT 	=  (BIT1 | BIT2 | BIT3 | BIT4 | BIT5);
      P1IE      = (0x08 | 0x10 | 0x20);
      P1IES     = (0x08 | 0x10 | 0x20);
      P1IFG     = (0x08 | 0x10 | 0x20);
      P1SEL     =  0x04;                   // Set selection register 1 for timer-function
    
    
    
      TA0CCTL1  = OUTMOD_7;                // Reset/set
      TA0CCR0   = 20000;                   // Period
      TA0CCR1   = 1500;                    // Duty-cycle
      TA0CTL    = (TASSEL_2 | MC_1);       // SMCLK, timer in up-mode
      _BIS_SR(GIE);
    
      while( 1 )                           // Endless-loop (main-program)
      {}
    
      }
    #pragma vector=PORT1_VECTOR
    __interrupt void P1_ISR(void)
    {
    	if( (P1IFG & 0x08) )               // Button at P1.3 pressed (S2 on LaunchPad)
        {
          TA0CCR1 = 1000;                  // Servo in middle position (1.5ms)
          P2OUT ^= ~(BIT1 | BIT2 | BIT3 | BIT4 | BIT5);
          P1OUT ^= ~(BIT6+BIT1);
          P1OUT ^= BIT6;
          P2OUT ^= (BIT1+BIT2+BIT3+BIT5+BIT4);
    
          P1IES ^= BIT3;
    
    
        }
        else if( (P1IFG & 0x10) )          // Button at P1.4 pressed
        {
          TA0CCR1 = 1500;                  // Servo in minimum position (1.0ms)
          P2OUT ^= ~(BIT1 | BIT2 | BIT3 | BIT4 | BIT5);
          P1OUT ^= ~(BIT6+BIT1);
          P2OUT ^= (BIT1+BIT4);
          P1IES ^= BIT4;
    
    
    
    
        }
        else if( (P1IFG & 0x20) )          // Button at P1.5 pressed
        {
          TA0CCR1 = 2000;                  // Servo in maximum position (2.0ms)
          P2OUT ^= ~(BIT1 | BIT2 | BIT3 | BIT4 | BIT5);
          P1OUT ^= ~(BIT6+BIT1);
          P1OUT ^= BIT1;
          P2OUT ^= (BIT1+BIT2+BIT3+BIT5);
    
          P1IES ^= BIT5;
    
        }
        P1IFG &= ~(0x08 | 0x10 | 0x20);
    }
    

    So I am continue to make my 3 floor lift with interrupts and 7 segment display thanks to you guys I manage to make it work without segment display. But when I added the segment display its not working properly.(The numbers are not shows up right and when I press the P1.3, P1.5 wont work unless I press P1.4)And another problem is its not show the current level only shows when I continue to press it.

**Attention** This is a public forum