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.

MSP 432 SERVO 0 ~ 180 degrees problem

Hi, I have this code for my msp 432 and servo-motor sg90, my problem is:
- In the program I use my pin for PWM 2.4 but the when I try to use Another pin for PWM (2.5, 2.6, 2.7, 5.6) THESE pins do not work to PWM implementation on it.
- I can't make loop Between 0 and 180 degrees, I want to have a loop for this position and I try diferent approach but I do not have success, the below code works to make one time movement when I press play and pause button from CCS.

My code:

/*******************************************************************************
 *
 *                MSP432P401
 *                MSP432P401
 *             ----------------------
 *            /|\|                      |
 *             | |                      |
 *            --|RST    P2.4  |--> Output PWM
 *               |                      |
 *               |                      |
 *               |                      |
 *               |                      |
 *               |                      |
 *
 ******************************************************************************/
/* DriverLib Includes */
#include "driverlib.h"

/* Standard Includes */
#include <stdint.h>

#include <stdbool.h>

/* Timer_A PWM Configuration Parameter */
Timer_A_PWMConfig pwmConfig =
{
	//uint_fast16_t clockSource;
        TIMER_A_CLOCKSOURCE_SMCLK,
	//uint_fast16_t clockSourceDivider;
        TIMER_A_CLOCKSOURCE_DIVIDER_1,
	//uint_fast16_t timerPeriod;
	1300,
	//uint_fast16_t compareRegister;
        TIMER_A_CAPTURECOMPARE_REGISTER_1,
        //uint_fast16_t compareOutputMode;
        TIMER_A_OUTPUTMODE_RESET_SET,
		//uint_fast16_t dutyCycle;
        80
};

int main(void)
{
    /* Halting the watchdog */
    MAP_WDT_A_holdTimer();

    int a;

    /* Setting MCLK to REFO at 128Khz for LF mode setting SMCLK to 64Khz */
    MAP_CS_setReferenceOscillatorFrequency(CS_REFO_128KHZ);
    MAP_CS_initClockSignal(CS_MCLK, CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_1);
    MAP_CS_initClockSignal(CS_SMCLK, CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_2);
    MAP_PCM_setPowerState(PCM_AM_LF_VCORE0);

    // Configuring GPIO2.4 as peripheral output for PWM
    MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P2, GPIO_PIN4, GPIO_PRIMARY_MODULE_FUNCTION);

    // Configuring Timer_A to have a period of approximately 20ms
    MAP_Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfig);

    /* Sleeping when not in use */
    while (1)
    {
// -----------------------------------------
//    	if(pwmConfig.dutyCycle == 210)
//    	      pwmConfig.dutyCycle = 10;  // for 0
//    	else
//    	      pwmConfig.dutyCycle = 210; // for 180
// -----------------------------------------
//    	pwmConfig.dutyCycle = 10;  // for 0
//    	for(a=10000; a>0; a--){
//    	}
//    	pwmConfig.dutyCycle = 210; // for 180
// -----------------------------------------
        MAP_PCM_gotoLPM0();
        MAP_Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfig);
    }
}
  • Hello,
    The PWM on pin 2.4 is specifically the timer capture/compare output of register 1 (Capture Compare Register 1) of TimerA0: TA0.1. Ports 2.5-2.7 are the outputs of the other capture/compare register CCR2-4 respectively. Port 5.6 is associated with timerA2 and CCR1.

    To output another PWM on P5.6 you would simply need to setup the GPIO for P5.6 and also call the generate PWM API but pass TIMER_A2_BASE. Ports, 2.5-2.7 are port mapped pins which means that you can change which peripheral is output on these pins, specifically you could set it to TA0.1. Please follow this example in how to utilize the port mapping feature:

    dev.ti.com/.../

    Regards,
    Chris
  • I will try this, and I return with an answer THX.
  • Functioned what you told me, really thx, you can help me with a loop for the above program?
  • I was helped to solve the problem with the loop and implementation is described below:

    /*******************************************************************************
     *
     *                      MSP432P401R
     *                      MSP432P401R
     *                ----------------------
     *            /|\|                      |
     *             | |                      |
     *             --|RST         P2.4/P5.6 |--> Output PWM
     *               |                      |
     *               |                      |
     *               |                      |
     *               |                      |
     *               |                      |
     *
     ******************************************************************************/
    /* DriverLib Includes */
    #include "driverlib.h"
    
    /* Standard Includes */
    #include <stdint.h>
    
    #include <stdbool.h>
    
    /* Timer_A PWM Configuration Parameter */
    Timer_A_PWMConfig pwmConfig =
    {
    		//uint_fast16_t clockSource;
            TIMER_A_CLOCKSOURCE_SMCLK,
    		//uint_fast16_t clockSourceDivider;
            TIMER_A_CLOCKSOURCE_DIVIDER_1,
    		//uint_fast16_t timerPeriod;
    		1300,
        	//uint_fast16_t compareRegister;
            TIMER_A_CAPTURECOMPARE_REGISTER_1,
    		//uint_fast16_t compareOutputMode;
            TIMER_A_OUTPUTMODE_RESET_SET,
            //uint_fast16_t dutyCycle;
            10
    };
    
    // PWM - PIN - 5.6 - TIMER_A2_BASE
    // PWM - PIN - 2.4 - TIMER_A0_BASE
    
    int main(void)
    {
        /* Halting the watchdog */
        MAP_WDT_A_holdTimer();
    
       int a,b;
        /* Setting MCLK to REFO at 128Khz for LF mode setting SMCLK to 64Khz */
        MAP_CS_setReferenceOscillatorFrequency(CS_REFO_128KHZ);
        MAP_CS_initClockSignal(CS_MCLK, CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_1);
        MAP_CS_initClockSignal(CS_SMCLK, CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_2);
        MAP_PCM_setPowerState(PCM_AM_LF_VCORE0);
    
        // Configuring GPIO2.4 as peripheral output for PWM
        MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P5, GPIO_PIN6, GPIO_PRIMARY_MODULE_FUNCTION);
    
        // Configuring Timer_A to have a period of approximately 20ms
        MAP_Timer_A_generatePWM(TIMER_A2_BASE, &pwmConfig);
    
        b = 40;
        while (1)
        {
        	pwmConfig.dutyCycle = b;
        	b = b + 10;
        	if(b == 170)
        	b = 40;
            for(a=3000; a>0; a--); // change delay
    
        	MAP_Timer_A_generatePWM(TIMER_A2_BASE, &pwmConfig);
        }
    }

    My question is now why the above code works and this code doesn't work?

    int main(void)
    {
        int a,b;    
        b = 0;
    
        while (1)
        {
        	while(b != 170) {
        	b = b + 10;
        	pwmConfig.dutyCycle = b;
            for(a=1000; a>0; a--){}
        	}
    
        	while(b > 0) {
        	b = b - 10;
        	pwmConfig.dutyCycle = b;
            for(a=1000; a>0; a--);
        	}
        }
    }
  • Hello,
    Can you provide some more detail in what you are observing? If the duty cycle is set to '0', then you will have an issue with the peripheral trying to set the output when the timer rolls over and reaches '0' but the timer will also 'reset' the output at '0'. Please refer to the pwm description found in the TRM ( www.ti.com/.../slau356e.pdf ) and the driver library dev.ti.com/.../group__timera__api.html

    Regards,
    Chris
  • My problem is that my code described above with "while" do not work, instead works with code "if".
  • Have you been able to resolve this? The above code with the "while" is missing the API call to update the PWM. Can you provide the complete example?

    Chris
  • Hi Chris, I try to make the code to work with while condition but I resolv my problem with if contition:

    /*******************************************************************************
     *
     *                      MSP432P401R
     *                      MSP432P401R
     *                ----------------------
     *            /|\|                      |
     *             | |                      |
     *             --|RST             P5.6  |--> Output PWM
     *               |                      |
     *               |                      |
     *               |                      |
     *               |                      |
     *               |                      |
     *
     ******************************************************************************/
    /* DriverLib Includes */
    #include "driverlib.h"
    
    /* Standard Includes */
    #include <stdint.h>
    
    #include <stdbool.h>
    
    /* Timer_A PWM Configuration Parameter */
    Timer_A_PWMConfig pwmConfig =
    {
    		//uint_fast16_t clockSource;
            TIMER_A_CLOCKSOURCE_SMCLK,
    		//uint_fast16_t clockSourceDivider;
            TIMER_A_CLOCKSOURCE_DIVIDER_1,
    		//uint_fast16_t timerPeriod;
    		1300,
        	//uint_fast16_t compareRegister;
            TIMER_A_CAPTURECOMPARE_REGISTER_1,
    		//uint_fast16_t compareOutputMode;
            TIMER_A_OUTPUTMODE_RESET_SET,
            //uint_fast16_t dutyCycle;
            10
    };
    
    // PWM - PIN - 5.6 - TIMER_A2_BASE
    // PWM - PIN - 2.4 - TIMER_A0_BASE
    
    int main(void)
    {
        /* Halting the watchdog */
        MAP_WDT_A_holdTimer();
    
        int a,b,direction;
    
        /* Setting MCLK to REFO at 128Khz for LF mode setting SMCLK to 64Khz */
        MAP_CS_setReferenceOscillatorFrequency(CS_REFO_128KHZ);
        MAP_CS_initClockSignal(CS_MCLK, CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_1);
        MAP_CS_initClockSignal(CS_SMCLK, CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_2);
        MAP_PCM_setPowerState(PCM_AM_LF_VCORE0);
    
        // Configuring GPIO2.4 as peripheral output for PWM
        MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P5, GPIO_PIN6, GPIO_PRIMARY_MODULE_FUNCTION);
    
        // Configuring Timer_A to have a period of approximately 20ms
        MAP_Timer_A_generatePWM(TIMER_A2_BASE, &pwmConfig);
    
        b = 40;
        direction = 0;
    
        /* Sleeping when not in use */
        while (1)
        {
        	MAP_Timer_A_generatePWM(TIMER_A2_BASE, &pwmConfig);
    
        	if (directie == 1)
        	{
        		b = b - 5;
        		pwmConfig.dutyCycle = b;
        		if(b == 40) {
        			direction = 0;
        		}
    
        		for(a=700; a>0; a--);
        	}
        	else
        	{
    
        		pwmConfig.dutyCycle = b;
        		b = b + 5;
        		if(b == 170) {		
        			direction = 1;
        		}
    
        		for(a=700; a>0; a--);
        	}
        }
    }

**Attention** This is a public forum