cancel
Showing results for 
Search instead for 
Did you mean: 

stm32f407 TIM1 and TIM8 sync

zarkscon
Associate II
Posted on March 14, 2015 at 15:18

Hello I'm trying to synchronize TIM1 and TIM8 (slaves) via TIM2 (master).. I checked the manual and says it can be done (p. 554/1710).. Although TIM2 works fine, TIM1 and TIM8 are off..

Please check my code bellow and help me out!

/* Includes ------------------------------------------------------------------*/
#include ''stm32f4xx.h''
#include ''stm32f4xx_rcc.h''
#include ''stm32f4xx_gpio.h''
#include ''stm32f4xx_tim.h''
#include ''misc.h''
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
/* Private function prototypes -----------------------------------------------*/
void
TIM_Config(
void
);
/* Private functions ---------------------------------------------------------*/
int
main(
void
)
{
TIM_Config();
/* TIM1 Peripheral Configuration ----------------------------------------*/
/* TIM1 Slave Configuration: PWM1 Mode */
TIM_TimeBaseStructure.TIM_Period = 2;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 1;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
/* Slave Mode selection: TIM1 */
TIM_SelectSlaveMode(TIM1, TIM_SlaveMode_Gated);
TIM_SelectInputTrigger(TIM1, TIM_TS_ITR1);
/* TIM8 Peripheral Configuration ----------------------------------------*/
/* TIM8 Slave Configuration: PWM1 Mode */
TIM_TimeBaseStructure.TIM_Period = 2;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 1;
TIM_OC1Init(TIM8, &TIM_OCInitStructure);
/* Slave Mode selection: TIM8 */
TIM_SelectSlaveMode(TIM8, TIM_SlaveMode_Gated);
TIM_SelectInputTrigger(TIM8, TIM_TS_ITR1);
/* TIM2 Peripheral Configuration ----------------------------------------*/
/* Time Base configuration */
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = 255;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 4;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
/* Channel 1 Configuration in PWM mode */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_Pulse = 127;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC1Init(TIM2, &TIM_OCInitStructure);
/* Master Mode selection */
TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);
/* Select the Master Slave Mode */
TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);
/* TIM2 counter enable */
TIM_Cmd(TIM2, ENABLE);
/* TIM enable counter */
TIM_Cmd(TIM1, ENABLE);
TIM_Cmd(TIM8, ENABLE);
/* Main Output Enable */
TIM_CtrlPWMOutputs(TIM2, ENABLE);
while
(1)
{}
}
void
TIM_Config(
void
)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* GPIOA and GPIOC clocks enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC, ENABLE);
/* TIM1 and TIM8 clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_TIM8, ENABLE);
/* TIM2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
/* GPIOA Configuration: TIM1 and TIM2 Channel1 as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_0;
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_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* GPIOC Configuration: TIM8 Channel1 as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* Connect TIM pins to AF1 */
GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_TIM1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_TIM2);
/* Connect TIM pins to AF3 */
GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM8);
}

Thanks in advance #discovery #stm32 #stm32f4
24 REPLIES 24
Posted on March 16, 2015 at 18:48

I can't see how reset mode would help me out

Because you said your wanted to ''start'' the pair of timers together, presumably because they need to be phase aligned with each other. You only need to reset them once to have them phase aligned.

Gated would seem to suggest you are modulating the slave timers with a signal from the master timer.

HSE 80 MHz? HSE is the external clock, rated 1-50 MHz

Yes' I'm well aware that the prescaler/period of a timer relate to the output frequency as divided into the TIMCLK of the timer.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on March 16, 2015 at 18:50

Lose one of the -1

TimerPeriod = ((SystemCoreClock/2) / FREQUENCY) ; // Compute N
TIM_TimeBaseStructure.TIM_Period = TimerPeriod - 1; // N-1
TIM_TimeBaseStructure.TIM_Prescaler = 0;

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on March 16, 2015 at 19:44

// STM32 Phase Align PWM on TIM1/TIM8 via TIM2 STM32F4 Discovery - sourcer32@gmail.com
#include ''stm32f4_discovery.h''
#define FREQUENCY 42500 /* output frequency 42500 KHz */
/****************************************************************************/
void RCC_Configuration(void)
{
/* GPIOA and GPIOC clocks enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC, ENABLE);
/* TIM1 and TIM8 clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_TIM8, ENABLE);
/* TIM2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
}
/****************************************************************************/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* GPIOA Configuration: TIM1 and TIM2 Channel1 as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_0;
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_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* GPIOC Configuration: TIM8 Channel1 as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* Connect TIM pins to AF */
GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_TIM1); // PA8 TIM1_CH1
GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_TIM2); // PA0 TIM2_CH1
GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM8); // PC6 TIM8_CH1
}
/****************************************************************************/
void TIM1_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
uint32_t Period = (SystemCoreClock / FREQUENCY); // On APB2, fast clock, 16-bit
/* TIM1 Peripheral Configuration ----------------------------------------*/
/* TIM1 Slave Configuration: PWM1 Mode */
TIM_TimeBaseStructure.TIM_Period = Period - 1;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_Pulse = Period / 2; // 50/50
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable; // full qualified for TIM1/TIM8
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
/* Slave Mode selection: TIM1 */
TIM_SelectSlaveMode(TIM1, TIM_SlaveMode_Reset); // Phase align on initial trigger
TIM_SelectInputTrigger(TIM1, TIM_TS_ITR1); // ITR1 on TIM1 is TIM2_TRGO
}
/****************************************************************************/
void TIM8_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
uint32_t Period = (SystemCoreClock / FREQUENCY); // On APB2, fast clock, 16-bit
/* TIM8 Peripheral Configuration ----------------------------------------*/
/* TIM8 Slave Configuration: PWM1 Mode */
TIM_TimeBaseStructure.TIM_Period = Period - 1;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_Pulse = Period / 2; // 50/50 duty cycle
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable; // full qualified for TIM1/TIM8
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC1Init(TIM8, &TIM_OCInitStructure);
/* Slave Mode selection: TIM8 */
TIM_SelectSlaveMode(TIM8, TIM_SlaveMode_Reset); // Phase align on initial trigger
TIM_SelectInputTrigger(TIM8, TIM_TS_ITR1); // ITR1 on TIM8 is TIM2_TRGO
}
/****************************************************************************/
void TIM2_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
uint32_t Period = ((SystemCoreClock / 2) / 50); // 50Hz for chuckles, On APB1, slow clock, 32-bit
/* TIM2 Peripheral Configuration ----------------------------------------*/
/* Time Base configuration */
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_Period = Period - 1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
/* Channel 1 Configuration in PWM mode */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_Pulse = Period / 2; // 50/50
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OC1Init(TIM2, &TIM_OCInitStructure);
/* Master Mode selection */
TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Enable); // Trigger when enabled
/* Select the Master Slave Mode */
TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);
}
/****************************************************************************/
int main(void)
{
RCC_Configuration();
GPIO_Configuration();
TIM1_Configuration();
TIM8_Configuration();
TIM2_Configuration();
/* TIM enable counter */
TIM_Cmd(TIM1, ENABLE);
TIM_Cmd(TIM8, ENABLE);
/* Main Output Enable */
TIM_CtrlPWMOutputs(TIM1, ENABLE);
TIM_CtrlPWMOutputs(TIM8, ENABLE);
/* TIM2 counter enable */
TIM_Cmd(TIM2, ENABLE);
while(1);
}
/**************************************************************************************/
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf(''Wrong parameters value: file %s on line %d

'', file, line) */
/* Infinite loop */
while (1)
{
}
}
#endif

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
zarkscon
Associate II
Posted on March 18, 2015 at 13:14

Sorry for my late reply I was working on another project.. 

Your code works great!! I can see now how RESET mode works.. 

 Thanks a lot for the help you ROCK!! 

zarkscon
Associate II
Posted on March 24, 2015 at 14:55

I know this might be a little bit out of topic, but I have an issue with phase shift.. I know TOGGLE mode is preffered for such thing but it only counts the ON period of the pulse which means the half period of the pulse.. So by entering a value TIM.Pulse > TIM.Period it starts from the beggining.. Even some examples you wrote about 240degrees phase shift ([DEAD LINK /public/STe2ecommunities/mcu/Lists/STM32Discovery/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/STM32Discovery/%5bHELP%5d%20STM32F4%20generate%20PWM%203%20channel%20shift%20phase%20120%20degree%21&FolderCTID=0x01200200770978C69A1141439FE559EB459D75800084C20D8867EAD444A5987D47BE638E0F&currentviews=1388]here), I think it's just 60degrees.. 

Could you help me out solving this phase shift issue, 'cause, in my case at least, it matters which channel starts first.. Thanks in advance!!

Posted on March 24, 2015 at 16:08

But we went to such lengths to align them....

You can phase shift two timers by altering TIMx->CNT with respect to each other.

I don't have a scope to hand most of the time, and usually not a 3+ channel one, most of these examples are coded blind. I was trying to demonstrate 3 channels on the same timer with phase shift.

You might also want to look at the PWM1 and PWM2 modes and how they change where the signal goes up and down.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
zarkscon
Associate II
Posted on March 25, 2015 at 13:09

We alligned them so that they can start together or else they would have 300ns delay.. 

You dont need a 3 channel oscilloscope, you could only scope the 1st and 3rd channel and watch the phase shift is 60degrees..

Now I want to control the timers' phase.. Is there another way except using TIM.Pulse on toggle mode?? TIM.Pulse on pmw modes change only the duty cycle..

When you say TIMx_CNT you mean the TIM.Period or the TIM.Pulse? I think it's the TIM.Period, the TIM.Pulse is the TIMx_ARR I think..

Posted on March 25, 2015 at 13:25

When you say TIMx_CNT you mean the TIM.Period or the TIM.Pulse? I think it's the TIM.Period, the TIM.Pulse is the TIMx_ARR I think..

No, I mean TIMx_CNT (phase), the counters each have a single counting element, to provide a relative phase displacement. You'd leave TIMx_ARR (period) alone because presumably you want the same frequency/period.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
zarkscon
Associate II
Posted on March 25, 2015 at 15:21

I tried changing the TIMx_CNT, as you said, using your code with some changes on each timer configuration and commenting slave-mode configurations (with slave-mode doesn't work, they always start together)

/* Includes ------------------------------------------------------------------*/
#include ''stm32f4xx.h''
#include ''stm32f4xx_rcc.h''
#include ''stm32f4xx_gpio.h''
#include ''stm32f4xx_tim.h''
#include ''misc.h''
#define FREQUENCY 42500 /* output frequency 42500 KHz */
/****************************************************************************/
void
RCC_Configuration(
void
)
{
/* GPIOA and GPIOC clocks enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOC, ENABLE);
/* TIM1 and TIM8 clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_TIM8, ENABLE);
/* TIM2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
}
/****************************************************************************/
void
GPIO_Configuration(
void
)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* GPIOA Configuration: TIM1 and TIM2 Channel1 as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_0;
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_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* GPIOC Configuration: TIM8 Channel1 as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* Connect TIM pins to AF */
GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_TIM1); 
// PA8 TIM1_CH1
GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_TIM2); 
// PA0 TIM2_CH1
GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM8); 
// PC6 TIM8_CH1
}
/****************************************************************************/
void
TIM1_Configuration(
void
)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
uint32_t Period = (SystemCoreClock / FREQUENCY); 
// On APB2, fast clock, 16-bit
/* TIM1 Peripheral Configuration ----------------------------------------*/
/* TIM1 Slave Configuration: PWM1 Mode */
TIM1->CNT = 0x00000000;
TIM_TimeBaseStructure.TIM_Period = Period - 1;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
TIM_OCInitStructure.TIM_Pulse = Period / 2; 
// 50/50
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable; 
// full qualified for TIM1/TIM8
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
/* Slave Mode selection: TIM1 */
//TIM_SelectSlaveMode(TIM1, TIM_SlaveMode_Reset); // Phase align on initial trigger
//TIM_SelectInputTrigger(TIM1, TIM_TS_ITR1); // ITR1 on TIM1 is TIM2_TRGO
}
/****************************************************************************/
void
TIM8_Configuration(
void
)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
uint32_t Period = (SystemCoreClock / FREQUENCY); 
// On APB2, fast clock, 16-bit
/* TIM8 Peripheral Configuration ----------------------------------------*/
/* TIM8 Slave Configuration: PWM1 Mode */
TIM8->CNT = 0x00008000;
TIM_TimeBaseStructure.TIM_Period = Period - 1;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
TIM_OCInitStructure.TIM_Pulse = (Period / 2); 
// 50/50 duty cycle
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable; 
// full qualified for TIM1/TIM8
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC1Init(TIM8, &TIM_OCInitStructure);
/* Slave Mode selection: TIM8 */
//TIM_SelectSlaveMode(TIM8, TIM_SlaveMode_Reset); // Phase align on initial trigger
//TIM_SelectInputTrigger(TIM8, TIM_TS_ITR1); // ITR1 on TIM8 is TIM2_TRGO
}
/****************************************************************************/
void
TIM2_Configuration(
void
)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
uint32_t Period = ((SystemCoreClock / 2) / 50); 
// 50Hz for chuckles, On APB1, slow clock, 32-bit
/* TIM2 Peripheral Configuration ----------------------------------------*/
/* Time Base configuration */
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_Period = Period - 1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
/* Channel 1 Configuration in PWM mode */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_Pulse = Period / 2; 
// 50/50
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OC1Init(TIM2, &TIM_OCInitStructure);
/* Master Mode selection */
TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Enable); 
// Trigger when enabled
/* Select the Master Slave Mode */
TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);
}
/****************************************************************************/
int
main(
void
)
{
RCC_Configuration();
GPIO_Configuration();
TIM1_Configuration();
TIM8_Configuration();
//TIM2_Configuration();
/* TIM enable counter */
TIM_Cmd(TIM1, ENABLE);
TIM_Cmd(TIM8, ENABLE);
/* Main Output Enable */
TIM_CtrlPWMOutputs(TIM1, ENABLE);
TIM_CtrlPWMOutputs(TIM8, ENABLE);
/* TIM2 counter enable */
//TIM_Cmd(TIM2, ENABLE);
while
(1);
}

This code still doesn't work.. When I change this

/* TIM8 Peripheral Configuration ----------------------------------------*/
/* TIM8 Slave Configuration: PWM1 Mode */
TIM8->CNT = 0x00008000;

to that

/* TIM8 Peripheral Configuration ----------------------------------------*/
/* TIM8 Slave Configuration: PWM1 Mode */
TIM1->CNT = 0x00008000;

it somehow works, don't know why TIM1_CNT affect TIM8's configuration.. If you have any good explanation for that or any other way of using TIMx_CNT please tell me.. Thanks in advance!!
Posted on March 25, 2015 at 16:30

I've waded into this as deep as I'm comfortable with, it will take a lot of reading of the documentation, and experimenting to understand the functional limits of the PWM modes.

You're right the other example has 60 degree phase shifts, Ch1 @ 30 degrees, Ch2@90, Ch3@150

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..