AnsweredAssumed Answered

STM32f103 timer parallel synchronisation

Question asked by olliw on Oct 5, 2013
Latest reply on Oct 18, 2013 by olliw
Hey Everyone 

Using a STM32F103RB 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*/