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
zarkscon
Associate II
Posted on April 01, 2015 at 22:09

Hello clive1, I got another program which I'd like your help with..

I want to phase shift ch2 +180 deg compared to ch1.. My code is bellow:

#include <stm32f4xx_gpio.h>
#include <stm32f4xx_tim.h>
#include <stm32f4xx_rcc.h>
#include <misc.h>
GPIO_InitTypeDef gpioStructure;
TIM_TimeBaseInitTypeDef timerInitStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
NVIC_InitTypeDef nvicStructure;
void
InitializeLEDs()
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOE , ENABLE);
gpioStructure.GPIO_Pin = GPIO_Pin_13;
gpioStructure.GPIO_Mode = GPIO_Mode_OUT;
gpioStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &gpioStructure);
GPIO_WriteBit(GPIOD, GPIO_Pin_12 | GPIO_Pin_13, Bit_RESET);
gpioStructure.GPIO_Pin = GPIO_Pin_8;
gpioStructure.GPIO_Mode = GPIO_Mode_AF;
gpioStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &gpioStructure);
gpioStructure.GPIO_Pin = GPIO_Pin_11;
gpioStructure.GPIO_Mode = GPIO_Mode_AF;
gpioStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &gpioStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_TIM1);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource11, GPIO_AF_TIM1);
}
void
InitializeTimer()
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
timerInitStructure.TIM_Prescaler = 40000;
timerInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
timerInitStructure.TIM_Period = 500;
timerInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
timerInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM1, &timerInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
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_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
TIM_OC2Init(TIM1, &TIM_OCInitStructure);
TIM_OCInitStructure.TIM_Pulse = 250 ; 
/**50/50 duty cycle**/
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM1, ENABLE);
TIM_Cmd(TIM1, ENABLE);
TIM_CtrlPWMOutputs(TIM1, ENABLE);
TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
}
void
EnableTimerInterrupt()
{
nvicStructure.NVIC_IRQChannel = TIM1_UP_TIM10_IRQn;
nvicStructure.NVIC_IRQChannelPreemptionPriority = 0;
nvicStructure.NVIC_IRQChannelSubPriority = 0;
nvicStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&nvicStructure);
}
void
TIM1_UP_TIM10_IRQHandler(
void
)
{
if
(TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)
{
if
(TIM_GetCounter(TIM1) == 250)
{
TIM_OCInitStructure.TIM_Pulse = 250 ; 
/*50/50 duty cycle*/
TIM_OC2Init(TIM1, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM1, ENABLE);
}
}
}
int
main()
{
InitializeLEDs();
InitializeTimer();
EnableTimerInterrupt();
if
(TIM_GetCounter(TIM1) == 250)
{
TIM_OCInitStructure.TIM_Pulse = 250 ; 
/*50/50 duty cycle*/
TIM_OC2Init(TIM1, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM1, ENABLE);
}
for
(;;)
{
int
i;
for
(i = 0; i < 1000000; i++)
asm(
''nop''
);
GPIO_ToggleBits(GPIOD, GPIO_Pin_13);
}
}

Using the PWM mode, ch2 starts after +360 deg instead of +180 deg.. Using Toggle mode, without changing anything else, they start together.. What's more, the LED never goes ON on the last infinite loop.. I commented the whole infinite loop and worked as before.. Isn't that strange? I'd really like to know if there is a way to make ONE interrupt instead of continuous, though I think that leads us to a simple ''if'' condition.. Any help would be gratefull.. Thanks in advance!!
Posted on April 01, 2015 at 22:37

Wouldn't CH1, CH1N implicitly be 180 out of phase in the 50/50 case? Also perhaps two channels in PWM1 vs PWM2 modes?

The Update interrupt occurs when CNT transitions to zero, not midway through. You could use a CCx compare point to interrupt at specific values.

For exotic wave forms consider a TIM driven DMA to GPIOx->BSRR with a circular pattern buffer.
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 April 02, 2015 at 16:35

I don't want exotic waves.. Could you help me out with the CCx compare point and how to interrupt at specific values? 

I have in mind something like a loop using TIM_GetCompare1(TIM1) and inside enabling channel 2.. 

What do you mean by saying

''

Also perhaps two channels in PWM1 vs PWM2 modes''

? I don't think you can have different modes on the same timer.. 

Posted on April 02, 2015 at 23:10

Pretty sure you can program each channel in it's own mode.

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 April 04, 2015 at 08:50

Thanks a lot clive1, I didn't know that..

Well my problems have not been solved yet.. Let me tell you what I want to achieve:

I want 4 square pulses and their 4 complementaries with a break time. I chose TIM1 (2 square pulses and 2 complementary) and TIM8 (2 square pulses and 2 complementary) because they have fixed complementary outputs and break time. I want to control the phase shift between TIM1_CH1 and TIM1_CH2 (phase=F1) and between TIM8_CH1 and TIM8_CH2 (phase=F2), for any value (0 to 360 degrees). Finally, I want to control the phase shift between TIM1_CH1 and TIM8_CH1 (0 to 360 degrees).

Do you have any hint? Thanks in advance!