cancel
Showing results for 
Search instead for 
Did you mean: 

STM32f103 timer parallel synchronisation

waldmanns
Associate II
Posted on October 05, 2013 at 11:08

Hey Everyone

Using a

http://www.mikrocontroller.net/part/STM32F103

RB I want to use Tim2 and Tim3 for generating a PWM, and want to start them both together such that they run prefectly in sync. Unfortunately, this canonic case I didn't found described in the ref manual or timer AN, so I did some code myself which however doesn't work exactly

as wished.

In addition to the timers I use I2C, which I implemented with the CPAL_V1.2.0 library, which hangs up when I use ''my'' sync method.

Error/problem description: (1) When I use only I2C then I2C works perfectly. (2) When I use I2C and Tim2 and Tim3 WITHOUT my timer-synch-routine, i.e. when both timers are each started with TIM_Cmd(TIMx, ENABLE), then I2C works perfectly. (3) When I use I2C and Tim2 and Tim3 WITH my synch-routine, then everything works fine as long as I do NOT switch on the timer outputs by writing to TIM2->CCER und TIM3->CCER. (4) As soon as I write to the CCER registers, then the I2C hangs up sooner or later (within few couple seconds). (the timer do work as they should) I'm on this issue since quite some time now without success. In a hope that someone has an answer, Olli

Appendix: code fragments

/*this is the routine which starts the troubles and eventually makes

the I2C to hang up*/

void

motors_onoff_update() { uint16_t tim2_ccer, tim3_ccer; tim2_ccer |= (uint16_t)(

1

<<

4

) | (uint16_t)(

1

<<

8

) | (uint16_t)(

1

<<

12

); tim3_ccer |= (uint16_t)(

1

<<

0

) | (uint16_t)(

1

<<

4

) | (uint16_t)(

1

<<

8

); TIM2->CCER = tim2_ccer; TIM3->CCER = tim3_ccer; }

void

timer_init(

void

) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBase_InitStructure; TIM_OCInitTypeDef TIM_OC_InitStructure;

//Initialize clocks for TIM2, TIM3

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM3, ENABLE);

//Initialize clocks for GPIOA, GPIOB, AFIO

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);

//Configure pin TIM2 CH2-CH4 = PA1,PA2,PA3, TIM3 CH1-CH3 = PA6,PA7,PB0 as alternative function push-pull

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure);

//Configure TIM2, TIM3 time base

TIM_TimeBase_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBase_InitStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1; TIM_TimeBase_InitStructure.TIM_Period =

1024

-

1

;

//11kHz with F100RB, 35kHz with F103RB

TIM_TimeBase_InitStructure.TIM_Prescaler =

0

; TIM_TimeBaseInit(TIM2, &TIM_TimeBase_InitStructure); TIM_TimeBaseInit(TIM3, &TIM_TimeBase_InitStructure);

//Configure TIM2, TIM3 waveform

TIM_OC_InitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OC_InitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; TIM_OC_InitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset; TIM_OC_InitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC_InitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; TIM_OC_InitStructure.TIM_OutputState = TIM_OutputState_Disable; TIM_OC_InitStructure.TIM_OutputNState = TIM_OutputNState_Disable; TIM_OC_InitStructure.TIM_Pulse =

512

; TIM_OC2Init(TIM2, &TIM_OC_InitStructure); TIM_OC3Init(TIM2, &TIM_OC_InitStructure); TIM_OC4Init(TIM2, &TIM_OC_InitStructure); TIM_OC1Init(TIM3, &TIM_OC_InitStructure); TIM_OC2Init(TIM3, &TIM_OC_InitStructure); TIM_OC3Init(TIM3, &TIM_OC_InitStructure);

/*using the following to sync the timers makes the I2C to eventually hang up, see above*/

//Set Master/Slave such to synchronize both timers at enable

TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Enable); TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable); TIM_SelectInputTrigger(TIM3, TIM_TS_ITR1); TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Trigger); TIM_Cmd(TIM2, ENABLE);

// TIM_Cmd(TIM3, ENABLE); //is enabled by TIM2

/*if one would NOT use the 4 commands to sync the timers, but would enable Tim3

 using TIM_Cmd(TIM3, ENABLE) then everything works perfectly*/ }
2 REPLIES 2
Amel NASRI
ST Employee
Posted on October 18, 2013 at 10:55

Hi Olliw,

Are you configuring the pin PB5 as an alternate function output somewhere?

In the

http://www.st.com/st-web-ui/static/active/en/resource/technical/document/errata_sheet/CD00190234.pdf

, there should be a conflict between I2C1 & TIM3_CH2 in such case.

-Mayla-

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

waldmanns
Associate II
Posted on October 18, 2013 at 22:08

Hey Mayla

thx for your response 🙂

in the above project I neither use PB5 nor I2C1 (I use I2C2)

may I assume that the above code snippet would, in principle, be the way to go?

cheers, Olli

PS: I planed to use PB5 and I2C1 in another but related project... so your comment was in fact VERY helpful, thx!