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.

CCS/MSP430F5529: To stop PWM

Part Number: MSP430F5529

Tool/software: Code Composer Studio

Hello all,

I am using MSP430F5529 for stepper motor control.  I need to stop my motor exactly after given particular number of steps.  I could able to generate square waves continuously but fails to stop exactly after particular number of steps.  Can any one help to achieve this.  Thanks in advance.

  • Hello Dipu,
    you are using Timer for generating PWM.. You can take interrupt of timer and count the no of PWM steps. After required no you can change the mode of CCP...

    Regards,
    Vikas Chola
  • Hi Mr.Vikas Chola,
    Thanks for your replay & time. Can you please help me out with an example code.

    Regards,
    Dipu.
  • My issue is : When we had the implementation as per your above suggestion more number of PWM cycles were generated and not stopping the stepper motor after specified number of steps. It seems like the the time required for the ISR routine is more than the interrupt time width.

    So need help in generating specific number of PWM cycles without checking the count inside the timer interrupt. Please help.

    Regards,
    Dipu.
  • Show us some code. Until then, we're all just guessing.
  • One possibility is to set a separate timer to control how long the PWM channel runs.
    e,g PRF is 500kHz, you want 37 pulses. Set up a timer to run for 74 us. Start the timer and the clock to the PWM channel, kill the clock to the PWM channel when the timer expires.

    Another approach: wrap the PWM output back around to a counter-timer channel and configure said channel to generate an ISR after the desired number of pulses.

  • Hi Jeff,

    Thanks for your replay.  Can you please send me an example code for the second option that you have mentioned.  First option is not working out for me.

    Regards,

    Dipu.

  • MyCode.txt
    
    void void_GenerateStepInput() // function to generate step input
    {
    
    	XTimerPeriod    = 400;
    	void_EnableStepperMotor(XAxis);//Enable stepper motor along X Axis
    	Timer_B_outputPWMParam GenerateStepInputXParam = {0};//Setting TA2 parameters for step input generation.
    	GenerateStepInputXParam.clockSource 		   = TIMER_B_CLOCKSOURCE_SMCLK;
    	GenerateStepInputXParam.clockSourceDivider     = TIMER_B_CLOCKSOURCE_DIVIDER_1;
    	GenerateStepInputXParam.timerPeriod            = XTimerPeriod;
    	GenerateStepInputXParam.compareRegister        = TIMER_B_CAPTURECOMPARE_REGISTER_2;
    	GenerateStepInputXParam.compareOutputMode      = TIMER_B_OUTPUTMODE_TOGGLE;
    	GenerateStepInputXParam.dutyCycle              = XTimerPeriod/2;
    	Timer_B_outputPWM(TIMER_B0_BASE,&GenerateStepInputXParam); //step input generation 
    }
    void TIMER0_B1_SpecificDistance_ISR(void)
    {
    	if(++TimerCountX >= NumberofSteps) 
    	{
    		void_TerminateStepInput();
    		Timer_B_disableCaptureCompareInterrupt(TIMER_B0_BASE,TIMER_B_CAPTURECOMPARE_REGISTER_2);
    		TimerCountX = 0;
    	}
    
    	Timer_B_clearCaptureCompareInterrupt(TIMER_B0_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_2);
    }
    Hi Bruce,

    Thanks for your replay.  My code is attached herewith.

    Regards,

    Dipu.

  • This seems to be missing void_TerminateStepInput, which was kind of the point. That said:

    The quickest way to stop the PWM and leave the output at 0 (low) would be: "TB0CCTL2 &= ~(OUTMOD_7|OUT);//OUTMOD=0,OUT=0". [I don't know the DriverLib language for that.]

    Doing that in the CCR2 interrupt (as you appear to be doing) would probably result in a very short "glitch" pulse, which may or may not be forgiven. I would suggest doing this in a TBCCR0 (or TBIFG) interrupt instead. By my reading, the signal at that moment would be 0, and will stay that way for 200 clocks, so you shouldn't see any glitch.

    Is there any chance that what you're seeing is actually overshoot from the abrupt stoppage of the pulse train?

    [Edit: Fixed goof in register name. Twice.]

  • code that demonstrate basic pulse counting follows; you could easily change this to use an ISR to handle the CCIFG-has-been set condition, rather than polling for it.

    // original development :
    // '5528 and an MSP-TS430RGC64USB target board
    // count negative pulses on P1.6/pin24 - internal pullup is used,
    // so P1.6/pin24 is normally HIGH


    #include <msp430.h>


    void begin_counting( unsigned target_count)
    {

    // stop counting - clear lower bit of MC field
    TA1CTL &= ~BIT4;
    // set current count
    TA1R = 0;
    // set the desired pulse count
    TA1CCR0 = target_count;
    // clear CCIFG - table 17-6 of SLAU208
    TA1CCTL0 &= ~CCIFG;
    // resume counting - set lower bit of MC field
    TA1CTL |= BIT4;
    }


    void main(void)
    {
    WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
    P1DIR |= 0x01; // set P1.0 as output (an LED is attached to pin)

    // enable pull on p1.6
    P1REN |= BIT6;
    // set pull to be "up"
    P1OUT |= BIT6;

    // TA1CTL - MC is 01 binary for count-up mode
    TA1CTL = 0x10;

    // set P1SEL.6 so that P1.6 functions as TA1CLK input
    // see table 6-46 of SLAS590
    P1SEL |= BIT6;

    begin_counting( 20 );

    for(;;)
    {

    // toggle the LED after each set of pulses
    if (TA1CCTL0 & CCIFG)
    {
    P1OUT ^= BIT0;
    begin_counting( 20 );
    }


    } // end for(ever)

    } // end main()

**Attention** This is a public forum