cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F7 casual PWM period

Alessio Fiammenghi
Associate II
Posted on March 01, 2017 at 11:02

Hello, I'm a new member on the forum.

I'm working on a stm32f7 and I need to generate a 10 kHz PWM from TIMER 13. I have a very strange problem. Sometimes when I turn on my board, the PWM period is totally wrong, it is around 2,3 seconds intead of 100 us. I have tried to reset and to reprogram the board but the period doesn't change. Then I've tried to set a very high frequency PWM, near to the clock frequency that feeds the timer and progressively I have reduced this frequency to see if the corresponding period match with my expectation. In this way the PWM period is correct at every flash of the board. 

The clock that feeds the TIMER 13 is at 216 Mhz. I use a tim period of 0x5460 to generate the 100 us period. I Have also tried to subtract 1 but this was not the solution. Maybe my board works fine for one or two days and then the problem reappears.

Same problem on the STM32F746 DISCOVERY demo board and on a custom board.

I use KEIL.

Here there is the function call:

         freq_pwm_wave_init(0x5460);

The Timer settings are the following:

void freq_pwm_wave_init(uint32_t period)

{

        /*

       HSE: 8 Mhz

            /8 = 1 Mhz

            *432 = 432 Mhz

            /2 = 216 Mhz = SYSCLK

            /1 (AHB)Prescaler = 216

            /1 (vedere RCC_ClkInitStruct.APB2CLKDivider =RCC_HCLK_DIV1 in main.c)

            *1 (se parametro precedente = 1 se no *2)

            /prescaler

            /period

          = FREQ hz

        */

        

    HAL_TIM_PWM_DeInit(&tdHandle_pwm_tim);

    fUser2bios_DebugPrintf('Start PWM init...');

    

    TIM_OC_InitTypeDef         tdOCInit_pwm_tim;

    TIM_Base_InitTypeDef       tdBInit_pwm_tim;

    TIM_ClockConfigTypeDef     tdCConfig_pwm_tim;

    HAL_StatusTypeDef        tdStatus_pwm_tim;

    

    tdBInit_pwm_tim.Prescaler             = 0x00;

    tdBInit_pwm_tim.ClockDivision         = TIM_CLOCKDIVISION_DIV1;

    tdBInit_pwm_tim.CounterMode         = TIM_COUNTERMODE_UP;

    tdBInit_pwm_tim.Period                 = (uint16_t)period;

    tdBInit_pwm_tim.RepetitionCounter     = 0x0;

    

    tdCConfig_pwm_tim.ClockFilter         = 0x0;

    tdCConfig_pwm_tim.ClockPolarity     = TIM_ETRPOLARITY_NONINVERTED;

    tdCConfig_pwm_tim.ClockPrescaler    = TIM_CLOCKPRESCALER_DIV1;

    tdCConfig_pwm_tim.ClockSource         = TIM_CLOCKSOURCE_INTERNAL ;

    

    tdHandle_pwm_tim.Instance     = pwm_timer.timer;

    tdHandle_pwm_tim.Init         = tdBInit_pwm_tim;

    

    tdOCInit_pwm_tim.OCMode     = TIM_OCMODE_PWM1;

    tdOCInit_pwm_tim.Pulse         = tdBInit_pwm_tim.Period / 2 ;//0x07F ;

    tdOCInit_pwm_tim.OCPolarity = TIM_OCPOLARITY_HIGH;

    

    tdStatus_pwm_tim = HAL_TIM_PWM_Init(&tdHandle_pwm_tim);

    if(tdStatus_pwm_tim != HAL_OK)

    {

        fUser2bios_DebugPrintf('Errore HAL_TIM_PWM_Init');

        return;

    }

    

    tdStatus_pwm_tim = HAL_TIM_ConfigClockSource(&tdHandle_pwm_tim, &tdCConfig_pwm_tim);

    if(tdStatus_pwm_tim != HAL_OK)

    {

        fUser2bios_DebugPrintf('Errore HAL_TIM_ConfigClockSource');

        return;

    }

    

    

    tdStatus_pwm_tim = HAL_TIM_PWM_ConfigChannel(&tdHandle_pwm_tim, &tdOCInit_pwm_tim, TIM_CHANNEL_1);

    if(tdStatus_pwm_tim != HAL_OK)

    {

        fUser2bios_DebugPrintf('Errore HAL_TIM_PWM_ConfigChannel');

        return;

    }

    

    

    tdStatus_pwm_tim = HAL_TIM_PWM_Start(&tdHandle_pwm_tim, TIM_CHANNEL_1);

    if(tdStatus_pwm_tim != HAL_OK)

    {

        fUser2bios_DebugPrintf('Errore HAL_TIM_PWM_Start');

        return;

    }

    

    fUser2bios_DebugPrintf('PWM OK\n');

}

 

And the GPIO settings are the following:

void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)

{

    GPIO_InitTypeDef  GPIO_InitStruct_pwm;

    

    gpio_clock_init(pwm_timer.pwm_gpio.GPIOx);    //Init clock GPIO

    timer_clock_init(pwm_timer.timer);            

    

    GPIO_InitStruct_pwm.Pin       = pwm_timer.pwm_gpio.GPIO_Pin;  //PF8

    GPIO_InitStruct_pwm.Mode      = GPIO_MODE_AF_PP;

    GPIO_InitStruct_pwm.Pull      = GPIO_NOPULL;

    GPIO_InitStruct_pwm.Speed     = GPIO_SPEED_HIGH;

    GPIO_InitStruct_pwm.Alternate = pwm_timer.alternate_func_gpio;  //GPIO_AF9_TIM13

    HAL_GPIO_Init(pwm_timer.pwm_gpio.GPIOx, &GPIO_InitStruct_pwm);

}

#pwm-wrong-period #discovery-board #stm32f7 #pwm
3 REPLIES 3
Posted on March 01, 2017 at 11:26

Output the system clock onto a MCO and observe when PWM is not what you expect.

JW

Posted on March 01, 2017 at 11:38

Thanks JW, I'll do this test as soon as the problem will reappear. Anyway I think that system Clock is correct because I have also a debug serial port at 115200 of baud rate and it works fine even when the PWM period is wrong... 

Another important thing I have forgot to explain before is that I have started the board in debug mode and I've cheked the content of the ARR register of the TIMER 13 and it is always correct!

Posted on March 01, 2017 at 11:49

Anyway I think that system Clock is correct because I have also a debug serial port at 115200 of baud rate and it works fine even when the PWM period is wrong...

Sounds reasonable.

I don't know if and how  this may be the culprit but at all cases you should make sure that you fill in completely these structures:

   TIM_OC_InitTypeDef         tdOCInit_pwm_tim;

    TIM_Base_InitTypeDef       tdBInit_pwm_tim;

    TIM_ClockConfigTypeDef     tdCConfig_pwm_tim;

or init them explicitly using the dedicated initialization functions.

JW

PS. If the problem occurs, read out all the timer registers and post them here.