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.

PWM on TMS570 with variable Duty Cycle and Frequency

Other Parts Discussed in Thread: HALCOGEN, TMS570LS1115

Hello,

I am new to the TMS570.

In my application (motor control), I need PWM outputs with variable duty cycle and frequency. I tried to use HALCOGEN to generate source code for PWM. But it produces constant-frequency and constant-dutycycle source code as I have attached below.

How can I modify the HALCOGEN generated source code to vary PWM parameters? I have highlighted the bits regarding the duty cycle and frequency (/* Data */ sections).

Thanks!

Arif

   /* MOV64: PWM 0 -> Duty Cycle Update
    *         - Instruction                  = 41
    *         - Next instruction             = 42
    *         - Conditional next instruction = 2
    *         - Interrupt                    = 1
    *         - Pin                          = 8
    */
    {
        /* Program */
        0x00054201U,
        /* Control */
        (0x00004007U | (uint32)((uint32)1U << 22U) | (uint32)((uint32)8U << 8U) | (uint32)((uint32)3U << 3U)),
        /* Data */
        45184U,

        /* Reserved */
        0x00000000U
    },
    /* MOV64: PWM 0 -> Period Update
    *         - Instruction                  = 42
    *         - Next instruction             = 3
    *         - Conditional next instruction = 41
    *         - Interrupt                    = 2
    *         - Pin                          = na
    */
    {
        /* Program */
        0x00006202U,
        /* Control */
        (0x00052007U),
        /* Data */
        89984U,

        /* Reserved */
        0x00000000U
    },

  • Hello Arif,

    I have copied one of our NHET experts to walk you through what you will need to do in order to achieve the variable duty cycle. He should get back with you soon.

  • Arif,

    This is a good post to start with and there are links to differnet implementations you can try.

    http://e2e.ti.com/support/microcontrollers/hercules/f/312/p/284151/993495.aspx#993495

     

  • Hello Chuck, Hello David,

    Thanks a lot for your responses.

    I have examined the page you advised. On the other hand, I tried to generate a code through Halcogen and compile it in CCS. When I check the functions in het.c source code which is generated by halcogen, I see a function which I assume as what I am actually looking for.

    To set duty cycle:

    void pwmSetDuty(hetRAMBASE_t * hetRAM, uint32 pwm, uint32 pwmDuty) 

    And to set period:

    pwmSetSignal(hetRAMBASE_t * hetRAM, uint32 pwm, hetSIGNAL_t signal)

    I am confused about the arguments of these functions. How should I determine the parameters of these functions to generate a pwm signal with a period and duty cycle I specify?

    /** @fn void pwmSetDuty(hetRAMBASE_t * hetRAM, uint32 pwm, uint32 pwmDuty)
    *   @brief Set duty cycle
    *   @param[in] hetRAM Pointer to HET RAM:
    *              - hetRAM1: HET1 RAM pointer
    *              - hetRAM2: HET2 RAM pointer
    *   @param[in] pwm Pwm signal:
    *              - pwm0: Pwm 0
    *              - pwm1: Pwm 1
    *              - pwm2: Pwm 2
    *              - pwm3: Pwm 3
    *              - pwm4: Pwm 4
    *              - pwm5: Pwm 5
    *              - pwm6: Pwm 6
    *              - pwm7: Pwm 7
    *   @param[in] pwmDuty duty cycle in %.
    *
    *   Sets a new duty cycle on the given pwm signal
    */
    /* SourceId : HET_SourceId_004 */
    /* DesignId : HET_DesignId_004 */
    /* Requirements : HL_SR366 */
    void pwmSetDuty(hetRAMBASE_t * hetRAM, uint32 pwm, uint32 pwmDuty)
    {
        uint32 action;
        uint32 pwmPolarity =0U;
        uint32 pwmPeriod = hetRAM->Instruction[(pwm << 1U) + 42U].Data + 128U;
        if(hetRAM == hetRAM1)
        {
            pwmPolarity = s_het1pwmPolarity[pwm];
        }
        else
        {
        }
        if (pwmDuty == 0U)
        {
            action = (pwmPolarity == 3U) ? 0U : 2U;
        }
        else if (pwmDuty >= 100U)
        {
            action = (pwmPolarity == 3U) ? 2U : 0U;
        }
        else
        {
            action = pwmPolarity;
        }
    
        hetRAM->Instruction[(pwm << 1U) + 41U].Control = ((hetRAM->Instruction[(pwm << 1U) + 41U].Control) & (~(uint32)(0x00000018U))) | (action << 3U);
        hetRAM->Instruction[(pwm << 1U) + 41U].Data = (uint32)((pwmPeriod * pwmDuty) / (uint32)100U) + 128U;
    }
    
    
    /** @fn void pwmSetSignal(hetRAMBASE_t * hetRAM, uint32 pwm, hetSIGNAL_t signal)
    *   @brief Set period
    *   @param[in] hetRAM Pointer to HET RAM:
    *              - hetRAM1: HET1 RAM pointer
    *              - hetRAM2: HET2 RAM pointer
    *   @param[in] pwm Pwm signal:
    *              - pwm0: Pwm 0
    *              - pwm1: Pwm 1
    *              - pwm2: Pwm 2
    *              - pwm3: Pwm 3
    *              - pwm4: Pwm 4
    *              - pwm5: Pwm 5
    *              - pwm6: Pwm 6
    *              - pwm7: Pwm 7
    *   @param[in] signal signal
                   - duty cycle in %.
    *              - period period in us.
    *
    *   Sets a new pwm signal
    */
    /* SourceId : HET_SourceId_005 */
    /* DesignId : HET_DesignId_005 */
    /* Requirements : HL_SR367 */
    void pwmSetSignal(hetRAMBASE_t * hetRAM, uint32 pwm, hetSIGNAL_t signal)
    {
        uint32 action;
        uint32 pwmPeriod = 0U;
        uint32 pwmPolarity = 0U;
        float32 temp = 0.0F;
    
        if(hetRAM == hetRAM1)
        {
            temp = ((float32)signal.period * 1000.0F) / 1422.222F;
            pwmPeriod = (uint32)temp << 7U;
            pwmPolarity = s_het1pwmPolarity[pwm];
        }
        else
        {
        }
        if (signal.duty == 0U)
        {
            action = (pwmPolarity == 3U) ? 0U : 2U;
        }
        else if (signal.duty >= 100U)
        {
            action = (pwmPolarity == 3U) ? 2U : 0U;
        }
        else
        {
            action = pwmPolarity;
        }
    
        hetRAM->Instruction[(pwm << 1U) + 41U].Control = ((hetRAM->Instruction[(pwm << 1U) + 41U].Control) & (~(uint32)(0x00000018U))) | (action << 3U);
        hetRAM->Instruction[(pwm << 1U) + 41U].Data = (uint32)((pwmPeriod * signal.duty) / (uint32)100U) + 128U;
        hetRAM->Instruction[(pwm << 1U) + 42U].Data = pwmPeriod - 128U;
    }

  • I'd love to hear an answer to this- I'm working on an application that needs to generate varied PWM signals according to external triggers, and so far I can't figure out quite what to do.


    What do I pass to the C functions

    void pwmSetDuty(hetRAMBASE_t * hetRAM, uint32 pwm, uint32 pwmDuty)

     

    and

    pwmSetSignal(hetRAMBASE_t * hetRAM, uint32 pwm, hetSIGNAL_t signal)

    ?

     

  • I've attached some code that I used to get the PWM working. I used pwmSetSignal to control the duty cycle and frequency, i'm not sure why they don't have a pwmSetFrequency function.


    The pwm0_signal structure elements can be modified in the debugger window or by your application.

    You may also find this post of interest.

    http://e2e.ti.com/support/microcontrollers/hercules/f/312/p/344034/1204654.aspx#1204654

    Jamie6888.sys_main.c

  • Hi everybody

    I saw this post and... Im going to control 12 different motors with different duty cyles, depending on the response of the PI controller...

    Why dont you check the reference manual? on the pages 725 and 765 comes how to do what you want, even example codes... using the ePWM... this is the case of the tms570ls1115 MCU but you could check on your MCUs and do something similar...

    best regards

    Mike

  • Hi Arif,

    Firstly you should define duty and period parameters in a struct for pwmSetSignal function because as you can see, signal parameter of this function is a struct.

    I assume you want to set a pwm signal on HET1 pin 12 (and you set this pin as pwm4 pin at HalCoGen) with %25 duty cycle and and 0.5 microsecond period you should pass the arguments to pwmSetSignal function like that:

        hetSIGNAL_t pwmSignal;  // hetSIGNAL_t is a struct which defined in het.h
    
        pwmSignal.duty = 25;
        pwmSignal.period = 0.5;
    
        pwmSetSignal(hetRAM1,pwm4,pwmSignal);

    I hope it helps.