2014-09-19 03:34 AM
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/... 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 shit to the third timer. The third timer uses only one compare register for the duty cycle. Here is my code: &sharpdefine PRESCALER_TX_PWM 1 &sharpdefine PERIODE_IN_TICKS 90 &sharpdefine PERIODE_IN_TICKS_LOC_OCS 88 //first timer &sharpdefine X_TX_PWM_TIM TIM2 &sharpdefine X_TX_PWM_PIN GPIO_Pin_15 &sharpdefine X_TX_PWM_PIN_SOURCE GPIO_PinSource15 &sharpdefine X_TX_PWM_AF GPIO_AF_TIM2 &sharpdefine X_TX_PWM_GPIO_PORT GPIOA &sharpdefine X_TX_PWM_GPIO_CLK RCC_AHB1Periph_GPIOA //second timer &sharpdefine Y_TX_PWM_TIM TIM3 &sharpdefine Y_TX_PWM_PIN GPIO_Pin_4 &sharpdefine Y_TX_PWM_PIN_SOURCE GPIO_PinSource4 &sharpdefine Y_TX_PWM_AF GPIO_AF_TIM3 &sharpdefine Y_TX_PWM_GPIO_PORT GPIOB &sharpdefine Y_TX_PWM_GPIO_CLK RCC_AHB1Periph_GPIOB //third timer &sharpdefine Z_TX_PWM_TIM TIM4 &sharpdefine Z_TX_PWM_PIN GPIO_Pin_9 &sharpdefine Z_TX_PWM_PIN_SOURCE GPIO_PinSource9 &sharpdefine Z_TX_PWM_AF GPIO_AF_TIM4 &sharpdefine Z_TX_PWM_GPIO_PORT GPIOB &sharpdefine Z_TX_PWM_GPIO_CLK RCC_AHB1Periph_GPIOB &sharpdefine X_TX_PWM_TIM_CLK RCC_APB1Periph_TIM2 &sharpdefine Y_TX_PWM_TIM_CLK RCC_APB1Periph_TIM3 &sharpdefine 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 shit and duty cycle using STM32F407VGT. I prefer to use only one Timer - TIM4. best regards, Stefan #pwm #timer-synchronization2014-09-19 05:23 AM
The timers are a bit ugly, you'd have to review/decipher the manual to get an understanding of what might be possible.
Toggle mode doesn't have to be 50/50. It is in the model where you program it and walk away. The alternative is to set the timer in maximal mode, and advance the CCRx settings at each interrupt and actively manage the placement of each edge.