AnsweredAssumed Answered

PWM 3 channel with shift phase 120 degree

Question asked by kosakovski.evgeni on May 2, 2015
Latest reply on May 21, 2015 by Forever_Embedded
Hi.

I am working with STM32F4 MCU and looking for help in the next question: 
I need to do PWM 3 channel with shift phase 120 degree on the start PWM operation. For example, PWM CH1 with 0 degrees, PWM CH2 with 120 degrees and PWM CH2 with 240 degrees.
Every PWM GPIOs are configured to start from 'Low' to 'High'. (This is OK). 
The problem is: When I configure 120 degrees **** for 40 KHz it calculated as 120 degrees shift from half time (the time that PWM is in the 'High' state). This means that **** between PWM channels is 60 degrees (4.2us) instead 120 degrees (8.4us). When I tried to multiply period as: TIM_OCInitStructure.TIM_Pulse = ((Period*2 * 3) / 3) - 1 this is does not work.

Where is my problem?
My email is tropinka06@gmail.com.
I know that there are similar posts, but no one with the same problem.

Thank you.
Evgeni Kosakovski

For this I use the next code:


void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
 
  /* GPIOE Configuration:  TIM1 on PE9/PE10/PE13 */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_11 | GPIO_Pin_13;
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_DOWN;
  GPIO_Init(GPIOE, &GPIO_InitStructure);
 
  /* Connect TIM1 pin  */
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource9,  GPIO_AF_TIM1); // PE9  TIM1_CH1  
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource11, GPIO_AF_TIM1); // PE11 TIM1_CH2
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource13, GPIO_AF_TIM1); // PE13 TIM1_CH3  
}
 
//******************************************************************************
 
void TIM1_Configuration(uint32_t PWM_Frequency)
{
    RCC_ClocksTypeDef RCC_ClocksStructure;
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    TIM_OCInitTypeDef  TIM_OCInitStructure;
    int Prescaler, Period;
    uint32_t TimerFrequency = 0;
    
    // Get clocks
     RCC_GetClocksFreq(&RCC_ClocksStructure);
    // For TIM1
     TimerFrequency = RCC_ClocksStructure.HCLK_Frequency;
    
    Prescaler = 1;


    Period = TimerFrequency / 2 / PWM_Frequency;   // KHz
    // The toggle halves the frequency
    /* Time base configuration */
    TIM_TimeBaseStructure.TIM_Period = Period - 1;
    TIM_TimeBaseStructure.TIM_Prescaler = Prescaler - 1;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
    
    /* Output Compare Toggle Mode configuration: Channel 1, 2 and 3 */
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCPolarity_High;
    
    /* Default unused fields TIM1 more sensitive */
    TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
    TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;




    /* Don't want to set 0 or Period, but have 3 points at 120 degrees from each other */
    TIM_OCInitStructure.TIM_Pulse = ((Period * 1) / 3) - 1;
    TIM_OC1Init(TIM1, &TIM_OCInitStructure);
    
    TIM_OCInitStructure.TIM_Pulse = ((Period * 2) / 3) - 1;
    TIM_OC2Init(TIM1, &TIM_OCInitStructure);
    
    TIM_OCInitStructure.TIM_Pulse = ((Period * 3) / 3) - 1;
    TIM_OC3Init(TIM1, &TIM_OCInitStructure);
    
    /* Enable pins, TIM1 more sensitive */
    TIM_CtrlPWMOutputs(TIM1, ENABLE);
    
    /* TIM1 enable counter */
    TIM_Cmd(TIM1, ENABLE);
}


int main(void)
{
  SysTickConfig();




  RCC_Configuration();
 
  GPIO_Configuration();
 
  TIM1_Configuration(40000); // 40KHz
  
  while (1)
  {}
}

Attachments

Outcomes