Post Go back to editing

PWM Duty Cycle

Category: Datasheet/Specs
Product Number: ADSP-SC584


I'm having trouble using the duty cycle on the PWM modules.

Im running on the PWM, channel D HI.

I'm running the PWM at 25kHz and the default duty cycle of 50% (when setting duty0 and duty1 to 0 on assymetric mode) comes out correct.

Similarly when I calculate the duty cycle for 0-50% it works as the duty0 and duty1 are positive. As soon as these are negative, it doesn't work. I cannot get 50%-100% duty cycle.

Please could someone clarify how to use the function: adi_pwm_setoutputdutycycle ?



Thread Notes

  • Hi Ben,

    From your description, it seems that you are having trouble achieving duty cycles beyond 50% when using negative values for duty0 and duty1 in asymmetric mode.

    In asymmetric PWM, the duty cycle represents the percentage of time that the signal is ON for each channel independently.
    The remaining time, where the signal is OFF, is also a part of the total cycle.

    If you want a 50% duty cycle in asymmetric mode, it means you want each channel to be ON for 25% of the total cycle (50% ON time across both channels).
    This naturally implies that the signal is OFF for the remaining 50% of the total cycle.

    For example: Here's the breakdown.

    duty0 = 25; // ON time for Channel 0 (25%)
    duty1 = 25; // ON time for Channel 1 (25%)

    With these settings, each channel is ON for 25% of the total cycle, and together they add up to a 50% duty cycle. The remaining 50% of the cycle is the time when both channels are OFF.

    So, in asymmetric PWM with a 50% duty cycle, the remaining 50% of the cycle is the OFF time across both channels.

    adi_pwm_SetOutputDutyCycle This function sets the duty cycle / phase of either the high side or low side output, of a PWM channel.

    The adi_pwm_SetOutputDutyCycle API configures PWM signals using a handle to the PWM device.

    It allows precise control over duty cycles for a selected channel pair, with parameters for the high or low side output.

    This flexibility enables customized PWM signal characteristics for specific application needs.

    Please refer the below path for more information of adi_pwm_SetOutputDutyCycle
    CrossCore® Embedded Studio 2.12.0 > System Run-Time Documentation > System Services and Device Drivers > ADSP-BF60x API Reference > Modules> adi_pwm_SetOutputDutyCycle

    And also, we recommend that to refer the below bsp path for more understanding.
    C:\Analog Devices\ADSP-SC58x_EZ-KIT_Lite-Rel1.1.0\ADSP-SC58x_EZ-KIT\Examples\services\pwm\PWM_Servo

    Hope this helps.

    Santha kumari.K

  • Hi Santha,

    Thank you for your reply.

    I still seem to not be able to get above 50% PWM using this method. And using duty0 = 12, duty1 = 12 does not result in 24% duty for me using this function.

    I am still confused with the adi_pwm_SetOutputDutyCycle API, as this seems to use a percentage of the period time as the duty, however, this doesn't work for over 50% duty cycle. I feel like I am using this function wrongly.

    I also don't seem to have access to the EZ-Lite example, is there a way you could paste in here/are there any other examples of this function being called alongside the adi_pwm_SetPeriod function?


    this is my code for initialsation in case this is wrong (this "625" gives me 25% duty, whereas using "1875" gives 0%):


    /* Set PADS_PCFG0.PWMGPSEL to Heightened precision on High and Low outputs */
    *pREG_PADS0_PCFG0 = *pREG_PADS0_PCFG0 + 0x10;

    /* open PWM */
    adi_pwm_Open(PWM_DEV, &PwmMemory, ADI_PWM_MEMORY_SIZE, &phPwm, Pwm_Callback, NULL);

    /* Enable HP on phase C+D */
    *pREG_PWM0_CHANCFG = *pREG_PWM0_CHANCFG + 0x10100000;

    /* enable channels */
    adi_pwm_OutputEnable(phPwm, pwmChannel, pwmOutputSide, true);

    /* configure period */
    adi_pwm_SetPeriod(phPwm, pwmChannel, 2500);

    /* configure timer mode */
    adi_pwm_SetTimerMode(phPwm, pwmChannel, true);
    adi_pwm_SetPulseMode(phPwm, pwmChannel, pwmOutputSide, ADI_PWM_PULSE_ASYMMETRICAL);

    adi_pwm_SetOutputDutyCycle(phPwm, pwmChannel, pwmOutputSide, (uint32_t)(625), (uint32_t)(625));

    /* configure timer interrupt */
    adi_pwm_InterruptEnable(phPwm, ADI_PWM_INTERRUPT_TIMER4, true);

    /* enable all PWM channels */
    adi_pwm_Enable(phPwm, true);




  • Hi Ben,

    Please find the attached PWM example from BSP path. This helps you to understand how to pass parameters inside adi_pwm_SetPeriod() & adi_pwm_SetOutputDutyCycle() APIs

    You can find the description of this example through this page Readme_PWM_Servo.html

    Best Regards,

  • Hi Santha,

    Thank you so much, you have been a great help!