Skip to main content
Mike Katz
Associate II
October 10, 2017
Question

Has anybody converted the PWM frequency and duty cycle measurement exmaple from the STM32CubeMx examples to use STM32CubeMx to configure the hardware (.ioc file to configure the timers)?

  • October 10, 2017
  • 2 replies
  • 3100 views
Posted on October 10, 2017 at 21:17

The 'STMCubeF2\Projects\STM32F207ZG-Nucleo\Examples\TIM\TIM_PWMInput' example configures the timers with direct calls to the HAL.

I am trying to keep all of the pin allocation and resource initialization within STM32CubMx itself.

Has anyone either created a .ioc file for this or measured frequency and duty cycle using STM32CubeMx to configure the timers?

Thanks in advance.

    This topic has been closed for replies.

    2 replies

    Vangelis Fortounas
    Associate II
    October 11, 2017
    Posted on October 11, 2017 at 17:34

    Hello!

    0690X00000608a1QAA.png

    PWM Input mode is selected from the combined channels droplist.

    To start the PWM Input , in your main function, call HAL_TIM_PWM_Start (for both channels).

    Inside TIM1 settings, the counter period(AR Register) must be higher than PWM period you try to measure.

    regards

    vf

    Mike Katz
    Mike KatzAuthor
    Associate II
    October 13, 2017
    Posted on October 13, 2017 at 00:25

    Thank you for your help.

    Do I need to enable the input capture interrupt or the global interrupt for the timer?

    Do you have a code sample I might look over or can you point me towards some documentation?

    Thanks again.

    Vangelis Fortounas
    Associate II
    October 14, 2017
    Posted on October 14, 2017 at 00:08

    Hello again.

    It is your choice to use interrupts or not, depending  on what you want to do. It is not mandatory.

    The initialization code produced from CubeMx.

    After Timer initialization in main(.) function, all your code will be

    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); 

    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);   

    Theese functions must de called once to start the PWM input  functionality.

    Parse the captured values values by calling

    HAL_TIM_ReadCapturedValue(&htim1, TIM_CHANNEL_1);    

    HAL_TIM_ReadCapturedValue(&htim1, TIM_CHANNEL_2);

    You can call theese functions every time you need to read the captured values.

    The User manual for HAL drivers is inside  HAL firmware  at \STM32Cube\Repository\STM32Cube_FW_F2_V1.6.0\Drivers\STM32F2xx_HAL_Driver.

    Read also about the IT and DMA versions of HAL_TIM_PWM_Start_IT, HAL_TIM_PWM_Start_DMA. It will helps you to decide the best solution for using timers.

    Take a look also inside stm32f2xx_hal_tim.c module. In the begining there is a summary of all tim functions and their use

    You can read also

    http://www.st.com/content/ccc/resource/technical/document/application_note/group0/91/01/84/3f/7c/67/41/3f/DM00236305/files/DM00236305.pdf/jcr:content/translations/en.DM00236305.pdf

    Regards

    vf

    Moh T.
    Visitor II
    December 20, 2017
    Posted on December 20, 2017 at 16:29

    Hi Mike & Vangelis,

    am also struggling with setting the PSC values to get pwm output of 28KHz for an IR Led, could you please tell me how did you manage to have the exact values to get 38KHz as an output. I am using stm32f030X, my settings are:

    uhPrescalerValue = (uint32_t)(SystemCoreClock / 16000000) - 1;

      __HAL_RCC_TIM3_CLK_ENABLE();

       TimHandle.Instance = TIM3;

       TimHandle.Init.Prescaler         = 1;

       TimHandle.Init.Period            = 200;

       TimHandle.Init.ClockDivision     = 0;

       TimHandle.Init.CounterMode       = TIM_COUNTERMODE_UP;

       TimHandle.Init.RepetitionCounter = 0;

       TimHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

    I want to use TIM3_CH2 /PA7 to generate a pwm, Thanks a lot in advance.

    Moh

    Tesla DeLorean
    Guru
    December 20, 2017
    Posted on December 20, 2017 at 17:06

    The math here is not complicated, the division is integer. Getting 38 KHz cleanly from 16 MHz will be a challenge. What frequency is your STM32F030X running at?

    The values for Period and Prescaler are written as N-1 (ie final value comparison)

    PWMFreq = (TIMCLK / (Prescaler + 1))  / (Period + 1)

    If it is simpler to factor

    PWMFreq = TIMCLK / (P * Q)

    Prescaler = Q - 1;

    Period = P -1;

    For 50% duty

    Pulse = ((Period + 1) * 100) / 50

    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    Moh T.
    Visitor II
    December 21, 2017
    Posted on December 21, 2017 at 09:36

    Hi Clive,

    the mcu is STM32F030K6, PWM=38KHZ

    SystemCoreClock = 8000000; // 8MHZ with the chip itself runs at 48MHz

    So setting so far are like following ?:

    ♯ define  PERIOD_VALUE       (uint32_t)(666-1)  /* Period Value  */

    .

    .

    .

    hPrescalerValue = (uint32_t)(SystemCoreClock / (38000*16)) - 1;

    imHandle.Init.Prescaler         = uhPrescalerValue;

    TimHandle.Init.Period            = PERIOD_VALUE;

    TimHandle.Init.ClockDivision     = 0;

    TimHandle.Init.CounterMode       = TIM_COUNTERMODE_UP;

    TimHandle.Init.RepetitionCounter = 0;

    TimHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

    .

    .

    .

    /*Configure PWM channel*/

       sConfig.OCMode       = TIM_OCMODE_PWM1;

       sConfig.OCPolarity   = TIM_OCPOLARITY_HIGH;

       sConfig.OCFastMode   = TIM_OCFAST_DISABLE;

       sConfig.OCNPolarity  = TIM_OCNPOLARITY_HIGH;

       sConfig.OCNIdleState = TIM_OCNIDLESTATE_RESET;

       sConfig.OCIdleState  = TIM_OCIDLESTATE_RESET;

      /* USER CODE END 2 */

      //sConfig.Pulse = 100;

       sConfig.Pulse = ((PERIOD_VALUE+1)*100)/50; // for 50% duty cycle