AnsweredAssumed Answered

Polarity PWM on STM32F4

Question asked by mas.thomas on Apr 8, 2014
Latest reply on Apr 8, 2014 by mas.thomas
Hello!

I am trying to create two square PWMs (duty 50%) with a controlled phase shift (0° to 90°). I am currently using TIM4 with 2 channels set on TIM_OCMode_Toggle and it is working OK.

The problem is hapening randomly when I try to change phase shift, I will get the phase of on of the PWM reversed (180° + my phase shift).

Is there a way to prevent this phenomenon? Maybee just a way to reset the state of the Pins when updating the Phase Shift would be nice...

here is my time initialisation if it is usefull:
void Config_Timers(void)
{
    // Create Hardware setup structures
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
    TIM_OCInitTypeDef TIM_OCInitStruct; 
      
    // First activate the Peripherals Clocks    
    RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM4, ENABLE );
  
  
    // Set Timer 4 Period to 1Hz by default
    PWM_Period = 1000;
  
    TIM_TimeBaseStructInit( &TIM_TimeBaseInitStruct );
    TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStruct.TIM_Prescaler = 0;
    TIM_TimeBaseInitStruct.TIM_Period = PWM_Period - 1;
    TIM_TimeBaseInit( TIM4, &TIM_TimeBaseInitStruct );
    // Set Output Compare on Timer4
      
    // Initialise PWM structure
    TIM_OCStructInit( &TIM_OCInitStruct );
    TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_Toggle;
  
    TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStruct.TIM_OutputNState = TIM_OutputNState_Disable;
    TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_Low;
    TIM_OCInitStruct.TIM_OCNPolarity = TIM_OCNPolarity_High;
    TIM_OCInitStruct.TIM_OCIdleState = TIM_OCIdleState_Set;
    TIM_OCInitStruct.TIM_OCNIdleState = TIM_OCIdleState_Reset;
      
    // Config Channel 3
    TIM_OCInitStruct.TIM_Pulse = 1; // start time
    TIM_OC3Init( TIM4, &TIM_OCInitStruct 
    // Config Channel 4
    TIM_OCInitStruct.TIM_Pulse = 1; // start time
    TIM_OC4Init( TIM4, &TIM_OCInitStruct );
      
    // Enable the Timer
    TIM_Cmd( TIM4, ENABLE );
      
    return;
}
  
void PWM_SetFrequency(unsigned int Frequency_kHz)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
  
    PWM_Period = 42000000/(long)Frequency_kHz;
  
    TIM_TimeBaseStructInit( &TIM_TimeBaseInitStruct );
    TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStruct.TIM_Prescaler = 1 - 1;
    TIM_TimeBaseInitStruct.TIM_Period = PWM_Period - 1;
    TIM_TimeBaseInit( TIM4, &TIM_TimeBaseInitStruct );
    // Set Output Compare on Timer4
  
    return;
}
  
void PWM_SetOffset(unsigned char Offset)
{
    int result;
    if(Offset != PWM_Offset)
    {
        PWM_Offset = Offset;
  
        // Change the starting time of the PWM
        result = (int)(((float)Offset/(float)255) * (float)(PWM_Period/2));
        if(result == 0) result =1;
        else if(result == PWM_Period) result = PWM_Period-1;
  
        TIM4->CCR3 = 1;
        TIM4->CCR4 = result;
    }
    return;
}

Best Regards,
Thomas

Outcomes