AnsweredAssumed Answered

Three PWM signal with variable phase **** and duty cycle

Question asked by hristozov.stefan on Sep 19, 2014
Latest reply on Sep 19, 2014 by Clive One
                                   
Hello,
           
            I want to generate three phase shifted PWM signals whit variable duty cycle and phase shift using SMT32F407VGT. 
            Is this possible? 
           
            I found this post on my.st.com https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/quadrature%20output%20-%20STM32F407&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&TopicsView=https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/AllItems.aspx¤tviews=71
            Here toggle mode is used. The phase shift is set with the parameter TIM_OCInitStructure.TIM_Pulse, but the duty cycle is always constant (50%). Is this true? 
           
            My second approach was to use three different timers and synchronize them using the link system.  
            My idea was to use two compare events on each timer. The match on the first on them determines the duty cycle and the match on the second generate a TRGO event starting the second timer. 
            In this way my second timer starts later, which gives me the phase shift.
            The second timer on the other hand uses, like the first timer, also two compare register, one for the duty cycle and one for the phase **** to the third timer.
            The third timer uses only one compare register for the duty cycle.
           
            Here is my code:
            #define PRESCALER_TX_PWM     1
            #define PERIODE_IN_TICKS     90
            #define PERIODE_IN_TICKS_LOC_OCS     88
           
            //first timer
            #define X_TX_PWM_TIM     TIM2
            #define X_TX_PWM_PIN GPIO_Pin_15
            #define X_TX_PWM_PIN_SOURCE     GPIO_PinSource15
            #define X_TX_PWM_AF     GPIO_AF_TIM2
            #define X_TX_PWM_GPIO_PORT GPIOA
            #define X_TX_PWM_GPIO_CLK           RCC_AHB1Periph_GPIOA
           
            //second timer
            #define Y_TX_PWM_TIM     TIM3
            #define Y_TX_PWM_PIN GPIO_Pin_4
            #define Y_TX_PWM_PIN_SOURCE     GPIO_PinSource4
            #define Y_TX_PWM_AF     GPIO_AF_TIM3
            #define Y_TX_PWM_GPIO_PORT GPIOB
            #define Y_TX_PWM_GPIO_CLK           RCC_AHB1Periph_GPIOB
           
            //third timer
            #define Z_TX_PWM_TIM     TIM4
            #define Z_TX_PWM_PIN GPIO_Pin_9
            #define Z_TX_PWM_PIN_SOURCE     GPIO_PinSource9
            #define Z_TX_PWM_AF     GPIO_AF_TIM4
            #define Z_TX_PWM_GPIO_PORT GPIOB
            #define Z_TX_PWM_GPIO_CLK           RCC_AHB1Periph_GPIOB
           
            #define X_TX_PWM_TIM_CLK     RCC_APB1Periph_TIM2
            #define Y_TX_PWM_TIM_CLK     RCC_APB1Periph_TIM3
            #define Z_TX_PWM_TIM_CLK     RCC_APB1Periph_TIM4
           
            void tx_pwm_init(void){
            TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
            TIM_OCInitTypeDef TIM_OCInitStructure;
           
            //init GPIOs
            tx_pwm_gpio_init();
           
            // Enable timer clocks
            RCC_APB1PeriphClockCmd(
            X_TX_PWM_TIM_CLK | Y_TX_PWM_TIM_CLK | Z_TX_PWM_TIM_CLK, ENABLE);
           
            /***********************************Configuration for TIM2 CH1 as X_TX_PWM*****************************************/
            // Time base configuration--------------------------------------------------
            TIM_TimeBaseStructure.TIM_Period = PERIODE_IN_TICKS;
            TIM_TimeBaseStructure.TIM_Prescaler = PRESCALER_TX_PWM;
            TIM_TimeBaseStructure.TIM_ClockDivision = 0;
            TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
           
            TIM_TimeBaseInit(X_TX_PWM_TIM, &TIM_TimeBaseStructure);
            TIM_TimeBaseInit(Y_TX_PWM_TIM, &TIM_TimeBaseStructure);
            TIM_TimeBaseInit(Z_TX_PWM_TIM, &TIM_TimeBaseStructure);
           
            // X_TX_PWM_TIM as master timer configuration in PWM1 Mode ----------------
            TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
            TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
            TIM_OCInitStructure.TIM_Pulse = PERIODE_IN_TICKS / 2;
            TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
           
            //CH1 match sets the and of the on-phase of the X, Y signal
            //CH4 match sets the and of the on-phase of the Z signal
            TIM_OC1Init(X_TX_PWM_TIM, &TIM_OCInitStructure);
            TIM_OC1Init(Y_TX_PWM_TIM, &TIM_OCInitStructure);
            TIM_OC4Init(Z_TX_PWM_TIM, &TIM_OCInitStructure);
           
            //X_TX_PWM_TIM CH2 generate a syc event for Y_TX_PWM_TIM timer
            TIM_OCInitStructure.TIM_Pulse = 30; //the phase shift is set here
            TIM_OC2Init(X_TX_PWM_TIM, &TIM_OCInitStructure);
            TIM_OC2Init(Y_TX_PWM_TIM, &TIM_OCInitStructure);
           
            // Select X_TX_PWM_TIM as master for Y_TX_PWM_TIM
            TIM_SelectMasterSlaveMode(X_TX_PWM_TIM, TIM_MasterSlaveMode_Enable);
            TIM_SelectOutputTrigger(X_TX_PWM_TIM, TIM_TRGOSource_OC1Ref);
           
            //Y_TX_PWM_TIM configurations ---------------------------------------------
            // Slave Mode selection: Y_TX_PWM_TIM
            TIM_SelectSlaveMode(Y_TX_PWM_TIM, TIM_SlaveMode_Reset);
            TIM_SelectInputTrigger(Y_TX_PWM_TIM, TIM_TS_ITR1);
           
            // Select the Master Slave Mode
            TIM_SelectMasterSlaveMode(Y_TX_PWM_TIM, TIM_MasterSlaveMode_Enable);
           
            // Master Mode selection: Y_TX_PWM_TIM
            TIM_SelectOutputTrigger(Y_TX_PWM_TIM, TIM_TRGOSource_OC2Ref);
           
            //Z_TX_PWM_TIM configurations ---------------------------------------------
            //Slave Mode selection: Z_TX_PWM_TIM
            TIM_SelectSlaveMode(Z_TX_PWM_TIM, TIM_SlaveMode_Reset);
            TIM_SelectInputTrigger(Z_TX_PWM_TIM, TIM_TS_ITR2);
           
            // TIM enable counter
            TIM_Cmd(X_TX_PWM_TIM, ENABLE);
            TIM_Cmd(Y_TX_PWM_TIM, ENABLE);
            TIM_Cmd(Z_TX_PWM_TIM, ENABLE);
            }
           
            With this code I can generate a PWM signal on TIM2 CH1, but it looks like the synchronization between the TIM2 and TIM3 doesn't work. 
            No PWM on TIM3 CH1. 
           
            My question is: is it possible to generate three PWM signal with variable phase **** and duty cycle using STM32F407VGT. 
            I prefer to use only one Timer - TIM4.
           
           
           
            best regards,
            Stefan 

Outcomes