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.

Need help!! moving servo motor using MSP430

Hi all,

      I'm having problem resetting the low power mode so that I can set it to different setting. I looked up some examples..here's my code.. I tried to use wait function between loop but it seems the problem with exiting the LPM0 and entering LPM0 again. Thanks in advance.

#include  <msp430x20x3.h>
void wait(int ms);
void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  P1DIR |= 0x0C;                            // P1.2 and P1.3 output
  P1SEL |= 0x0C;                            // P1.2 and P1.3 TA1/2 otions
     
  for (int i=1; i<3001; i++)                  // Rotate 10 times
  { TACCTL0=CCIE;
    CCR0 = 23260-1;                           // PWM Period/2
    CCTL1 = OUTMOD_7;                       // CCR1 reset/set
 
   if( i%200==0 )
   {  __disable_interrupt();
     CCR1=1582 ;                             //1582= 90 Degree UP
    TACTL = TASSEL_2+ MC_1;                  // ACLK, up-down mode
     _BIS_SR(LPM0_bits+GIE);__enable_interrupt();
  // CCTL1=0;
   }
   else if( i%300==0 )
   {    __disable_interrupt();
     CCR1= 1977;                            // 1977=Fall Back
   TACTL = TASSEL_2+ MC_1;                  // ACLK, up-down mode
    _BIS_SR(LPM0_bits+GIE); __enable_interrupt();
   }
   else if(i%1==0)
   {  __disable_interrupt();
     CCR1=700;                            //700= 0 Degree
      TACTL = TASSEL_2+ MC_1;                  // ACLK, up-down mode
    _BIS_SR(LPM0_bits+GIE);
     __enable_interrupt();
   }
   }
 
 
}


// __enable_interrupt();
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
  //wait(10);
  LPM0_EXIT; TACTL&=~OUTMOD_7;

}


//Wait a designated amount of time in milliseconds.
void wait(int ms)
{
volatile int i;
for(i=0; i<ms*3200; i++);
}

  • I do not know if this is causing the issue you see, but setting the GIE in the status register is equivalent to the __enable_interrupt().   In the 2xx family you should also setup the DCO since the timer is running off of the SMCLK.

    Regards

  • Hi,

    If I understood your source code, each time you start Timer A, the uC enters in LPM0. You are using Timer_A ISR to wakeup the uC. Try to use the instruction __low_power_mode_off_on_exit when returning from the interrupt.

    Best Regards,
    AES

  • Hello again,

                  Thanks for the help guys. After looking at examples and tutorials from TI and many tries, I managed to rotate the motor. Now I got another problem. The servo motor got two parts: one for up and down , one for left right rotation. It has two input wires for each of them. I connected the up down wire to pin 4 of msp430 F2013. However, i have no idea where to start, if i wanna to use both up-down and left-right rotation at same time. Should i connect the other wire to pin 3? All the example i found are usually using only Timer_A and there isn't any example that uses 2 variables at the same time. Also, I got error if i use CCR2 in my code. Thanks in advance for your help.

    Here's the code I wrote for up and down motor.

    #include <msp430x20x3.h>

    void main(void)
    {
      WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
      P1DIR |= 0x04;                            // P1.2 and P1.3 output
      P1SEL |= 0x04;                            // P1.2 and P1.3 TA1/2 otions

      int down=1;                               // controlling positon
      int mid=1;                                // 1=on , 0=off
      int fall=1;
     
      for(int L=1; L<6; L++)                    // Rotate 5 times
      {
      if (down==1)
      { 
      for (int i=1; i<31; i++)                
      { TACCTL0=CCIE;
     
        CCR0 = 23260-1;                           // PWM Period/2
        CCTL1 = OUTMOD_7;                         // CCR1 reset/set
     
      
          CCR1=700;                              //700= 0 Degree
          TACTL = TASSEL_2+ MC_1;                // SMCLK, up-down mode
         _BIS_SR(LPM0_bits+GIE);
       }
      }

      if (mid==1)
      {
      for (int j=1;j<31;j++)
      {
        CCR0=23260-1;
        CCTL1= OUTMOD_7;
        CCR1=1582;
        TACTL = TASSEL_2+MC_1;
        _BIS_SR(LPM0_bits+GIE);
      }
      }
     
      if (fall==1)
      {
      for (int k=1;k<31;k++)
      {
        CCR0=23260-1;
        CCTL1= OUTMOD_7;
        CCR1=2177;
        TACTL = TASSEL_2+MC_1;
        _BIS_SR(LPM0_bits+GIE);
      }
      }
      }
    }


    #pragma vector=TIMERA0_VECTOR
    __interrupt void Timer_A (void)
    {
      __low_power_mode_off_on_exit();
    }

  • The device is equipped with a TimerA2 module meaning that there are only two capture compare registers: TA0CCR0 and TA0CCR1.  CCR2 is not available on this device. If you want to create two different PWMs you will have to use the overflow (FFFF) to set the period.  Please refer to the code example msp430x20x3_ta_08.c.  You can also reference the example found in SLVU240a which creates three output PWMs with an A3.

    TACTL = TASSEL_2+ID_0+MC_0+TACLR+TAIE; // Timer clock = SMCLK = 8MHz

    TACCTL0 = CM_0+CCIS_2+OUTMOD_1; // All Output Units will set PWM outputs if

    TACCTL1 = CM_0+CCIS_2+OUTMOD_1; // TACCRx=TAR. Resetting PWM outputs is done

    TACCTL2 = CM_0+CCIS_2+OUTMOD_1; // by software.

    LEDptr=0;

    TACCR0=LED1[LEDptr>>2]; // LEDptr is shifted right twice,

    TACCR1=LED2[LEDptr>>2]; // this means divided by 4

    TACCR2=LED3[LEDptr>>2];

    ...

    // Timer_A Interrupt Service Routine:

    #pragma vector=TIMERA1_VECTOR

    __interrupt void ISR_TimerA(void)

    { P1OUT |= 0x01; // activate LEDs

    //--- update PWM duty cycle settings using colour table

    TACCR0=LED1[LEDptr>>2]; // LEDptr is shifted right twice,

    TACCR1=LED2[LEDptr>>2]; // this means divided by 4

    TACCR2=LED3[LEDptr>>2];

    //--- PWM signal generation

    TACTL &= ~TAIFG;

    TACCTL0 &= ~OUTMOD_7; // OUTMOD_0 => PWM output=L

    TACCTL0 |= OUTMOD_1; // OUTMOD_1 => set PWM output TA0 as soon as TACCR0=TAR

    TACCTL1 &= ~OUTMOD_7; // OUTMOD_0 => PWM output=L

    TACCTL1 |= OUTMOD_1; // OUTMOD_1 => set PWM output TA1 as soon as TACCR1=TAR

    TACCTL2 &= ~OUTMOD_7; // OUTMOD_0 => PWM output=L

    TACCTL2 |= OUTMOD_1; // OUTMOD_1 => set PWM otuput TA2 as soon as TACCR2=TAR

    // TAR = Timer_A counter

    }

     

     

     

     

**Attention** This is a public forum