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.
HI,
I am using the sample project from the TI MSPWARE library. However, the dutyCycle update does not actually change the duty cycle, but it changes the frequency. Has anybody run into this issue?
/* Timer_A PWM Configuration Parameter */ Timer_A_PWMConfig pwmConfig = { TIMER_A_CLOCKSOURCE_SMCLK, //clockSource TIMER_A_CLOCKSOURCE_DIVIDER_1, //clockSourceDivider 32000, //timerPeriod TIMER_A_CAPTURECOMPARE_REGISTER_0, //compareRegister TIMER_A_OUTPUTMODE_TOGGLE, //compareOutputMode 3200 //dutyCycle }; int main(void) { /* Halting the watchdog */ MAP_WDT_A_holdTimer(); /* 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 and P6.7 for button * interrupt */ MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P7, GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION); MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN1); MAP_GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN1); MAP_GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN1); /* Configuring Timer_A to have a period of approximately 500ms and * an initial duty cycle of 10% of that (3200 ticks) */ MAP_Timer_A_generatePWM(TIMER_A0_MODULE, &pwmConfig); /* Enabling interrupts and starting the watchdog timer */ MAP_Interrupt_enableInterrupt(INT_PORT1); MAP_Interrupt_enableSleepOnIsrExit(); MAP_Interrupt_enableMaster(); /* Sleeping when not in use */ while (1) { MAP_PCM_gotoLPM0(); } } /* Port1 ISR - This ISR will progressively step up the duty cycle of the PWM * on a button press */ void port1_isr(void) { uint32_t status = MAP_GPIO_getEnabledInterruptStatus(GPIO_PORT_P1); MAP_GPIO_clearInterruptFlag(GPIO_PORT_P1, status); if (status & GPIO_PIN1) { if(pwmConfig.dutyCycle == 28800) pwmConfig.dutyCycle = 3200; else pwmConfig.dutyCycle += 3200; MAP_Timer_A_generatePWM(TIMER_A0_MODULE, &pwmConfig); } }
I am using the MSP432P401R LaunchPad. Thanks for any help!
-Edgar
Hello Edgar,
Thank you for bringing this issue to our attention. You are correct, as the example currently stands it does not correctly output a PWM as stated in the description. The reason for this is that the pwmConfig structure alters the value of CCR0, which defines the timer period instead of the duty cycle. To fix this we need to change the compare register value to TIMER_A_CAPTURECOMPARE_REGISTER_[1/2/3/4/5/6] and change our output pin accordingly. Also, a toggling compare output mode will only keep the duty cycle at 50%, in order to have the duty cycle start at 10% and go up to 90% we need to change the mode to reset/set. The attached example utilizes CCR1 on pin 2.4 to create the proper PWM signal. I will make sure that this MSPWare code example is updated.
/* * ------------------------------------------- * MSP432 DriverLib - v2_20_00_08 * ------------------------------------------- * * --COPYRIGHT--,BSD,BSD * Copyright (c) 2014, Texas Instruments Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * --/COPYRIGHT--*/ /******************************************************************************* * MSP432 Timer_A - Variable PWM * * Description: In this example, the Timer_A module is used to create a precision * PWM with an adjustable duty cycle. The PWM initial period is 200 ms and is * output on P2.4. The initial duty cycle of the PWM is 10%, however when the * button is pressed on P1.1 the duty cycle is sequentially increased by 10%. * Once the duty cycle reaches 90%, the duty cycle is reset to 10% on the * following button press. * * MSP432P401 * ------------------ * /|\| | * | | | * --|RST P1.1 |<--Toggle Switch * | | * | | * | P2.4 |--> Output PWM * | | * | | * * Author: Timothy Logan *******************************************************************************/ /* DriverLib Includes */ #include "driverlib.h" /* Standard Includes */ #include <stdint.h> #include <stdbool.h> /* Timer_A PWM Configuration Parameter */ Timer_A_PWMConfig pwmConfig = { TIMER_A_CLOCKSOURCE_SMCLK, TIMER_A_CLOCKSOURCE_DIVIDER_1, 32000, TIMER_A_CAPTURECOMPARE_REGISTER_1, TIMER_A_OUTPUTMODE_RESET_SET, 3200 }; int main(void) { /* Halting the watchdog */ MAP_WDT_A_holdTimer(); /* 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 and P6.7 for button * interrupt */ MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P2, GPIO_PIN4, GPIO_PRIMARY_MODULE_FUNCTION); MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN1); MAP_GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN1); MAP_GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN1); /* Configuring Timer_A to have a period of approximately 500ms and * an initial duty cycle of 10% of that (3200 ticks) */ MAP_Timer_A_generatePWM(TIMER_A0_MODULE, &pwmConfig); /* Enabling interrupts and starting the watchdog timer */ MAP_Interrupt_enableInterrupt(INT_PORT1); MAP_Interrupt_enableSleepOnIsrExit(); MAP_Interrupt_enableMaster(); /* Sleeping when not in use */ while (1) { MAP_PCM_gotoLPM0(); } } /* Port1 ISR - This ISR will progressively step up the duty cycle of the PWM * on a button press */ void port1_isr(void) { uint32_t status = MAP_GPIO_getEnabledInterruptStatus(GPIO_PORT_P1); MAP_GPIO_clearInterruptFlag(GPIO_PORT_P1, status); if (status & GPIO_PIN1) { if(pwmConfig.dutyCycle == 28800) pwmConfig.dutyCycle = 3200; else pwmConfig.dutyCycle += 3200; MAP_Timer_A_generatePWM(TIMER_A0_MODULE, &pwmConfig); } }
Regards, Ryan
**Attention** This is a public forum