cancel
Showing results for 
Search instead for 
Did you mean: 

PWM 3 channel with shift phase 120 degree

tropinka06
Associate
Posted on May 02, 2015 at 16:41

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 shit for 40 KHz it calculated as 120 degrees shift from half time (the time that PWM is in the 'High' state). This means that shit 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)

  {}

}
1 REPLY 1
ceylan
Associate II
Posted on May 21, 2015 at 14:25

I think you find wrong period

Period = (timerfrequency / 2) / pwm_frequency

just a suggestion