cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F407VG Timers Synchronization question.

ArturasV
Senior
Posted on November 13, 2015 at 18:42

Hello everyone, i need some help, so if anyone could, i'd be grateful. I need to start two timers instantaneously at the same time, when external event happens. Lets say, rising edge on the pin should trigger two timers to start. How it should look like can be seen in RM0090 18.3.15 - Timer Synchronization, Figure 179. However, i am not able to achieve is and i dont quite understand from RM which Timers can work as masters and which ones can work as slaves. I was trying different kind of combinations, but here is my code for now (which is not doing what i want). 

#include ''main.h''

uint32_t counter = 0;

int main(void)

{

rcc_config();

get_system_clocks();

gpio_config();

timers_config();

GPIO_SetBits(GPIOD, GPIO_Pin_12);

while(1)

{

counter++;

}

}

void get_system_clocks(void)

{

RCC_GetClocksFreq(&rcc_struct);

}

void rcc_config(void)

{

RCC_AHB1PeriphClockCmd(RCC_AHB1ENR_GPIODEN, ENABLE);

RCC_AHB1PeriphClockCmd(RCC_AHB1ENR_GPIOAEN, ENABLE);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

}

void gpio_config(void)

{

/* Configure PD12, PD13 in output push-pull mode for LEDs. PD13 used as CS for SPI */

gpio_struct.GPIO_Pin = GPIO_Pin_12;

gpio_struct.GPIO_Mode = GPIO_Mode_OUT;

gpio_struct.GPIO_OType = GPIO_OType_PP;

gpio_struct.GPIO_Speed = GPIO_Speed_25MHz;

gpio_struct.GPIO_PuPd = GPIO_PuPd_NOPULL;

GPIO_Init(GPIOD, &gpio_struct);

/* TIM2 chennel2 configuration : PD.02 */

gpio_struct.GPIO_Pin = GPIO_Pin_6;

gpio_struct.GPIO_Mode = GPIO_Mode_AF;

gpio_struct.GPIO_Speed = GPIO_Speed_25MHz;

gpio_struct.GPIO_OType = GPIO_OType_PP;

gpio_struct.GPIO_PuPd = GPIO_PuPd_DOWN ;

GPIO_Init(GPIOA, &gpio_struct);

/* Connect TIM3 External trigger pin to AF2 */

GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_TIM3);

}

void timers_config(void)

{

/* Timer 3 Configuration */

timerbase_struct.TIM_Prescaler = 8400;

timerbase_struct.TIM_Period = 20000;

timerbase_struct.TIM_CounterMode = TIM_CounterMode_Up;

timerbase_struct.TIM_ClockDivision = TIM_CKD_DIV1;

timerbase_struct.TIM_RepetitionCounter = 0x00;

TIM_TimeBaseInit(TIM3, &timerbase_struct);

//TIM_ETRConfig(TIM3, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x00);

/* Timer 4 Configuration */

timerbase_struct.TIM_Prescaler = 8400;

timerbase_struct.TIM_Period = 20000;

timerbase_struct.TIM_CounterMode = TIM_CounterMode_Up;

timerbase_struct.TIM_ClockDivision = TIM_CKD_DIV1;

timerbase_struct.TIM_RepetitionCounter = 0x00;

TIM_TimeBaseInit(TIM4, &timerbase_struct);

timer_input_struct.TIM_Channel = TIM_Channel_1;

timer_input_struct.TIM_ICPolarity = TIM_ICPolarity_Rising;

timer_input_struct.TIM_ICSelection = TIM_ICSelection_DirectTI;

timer_input_struct.TIM_ICPrescaler = TIM_ICPSC_DIV1;

timer_input_struct.TIM_ICFilter = 0x0;

TIM_ICInit(TIM3, &timer_input_struct);

/* Configure Timer3 as master */

TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Enable);

TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);

TIM_SelectInputTrigger(TIM3, TIM_TS_ITR1);

TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Trigger);

/* Configure Timer4 as slave */

TIM_SelectInputTrigger(TIM4, TIM_TS_ITR1);

TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Trigger);

}

1 ACCEPTED SOLUTION

Accepted Solutions
ArturasV
Senior
Posted on November 18, 2015 at 17:31

The topic can be closed, i found the issue. It was problems with the debugger, i wasn't stopping Timers when MCU was halted.

View solution in original post

8 REPLIES 8
ArturasV
Senior
Posted on November 16, 2015 at 11:12

Okey, thanks waclawek.jan. For some reason, in my RM version for F4 i don't have the tables with Timers ITR which i found in RM, posted in the post you gave the link to 🙂 But it seems that im still doing something wrong. I want to start two Timers synchronously on external trigger. So i managed to do, but the difference between two timers seem to be too big and inappropriate. I see a big difference between two timers start, which i measured with scope and it is varying from 30 to 35ms, which is too much when you think that timers are running at 42MHz (of course psc 4200 gives only 10kHz). Could you check if there is something wrong with the code? 

void timers_config(void)

{

/* Timer 3 Configuration */

timerbase_struct.TIM_Prescaler = 4200;

timerbase_struct.TIM_Period = 40000;

timerbase_struct.TIM_CounterMode = TIM_CounterMode_Up;

timerbase_struct.TIM_ClockDivision = TIM_CKD_DIV1;

timerbase_struct.TIM_RepetitionCounter = 0x00;

TIM_TimeBaseInit(TIM3, &timerbase_struct);

TIM_ETRConfig(TIM3, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_Inverted, 0x0F);

/* Timer 4 Configuration */

timerbase_struct.TIM_Prescaler = 4200;

timerbase_struct.TIM_Period = 30000; // 10k tick = 1s

timerbase_struct.TIM_CounterMode = TIM_CounterMode_Up;

timerbase_struct.TIM_ClockDivision = TIM_CKD_DIV1;

timerbase_struct.TIM_RepetitionCounter = 0x00;

TIM_TimeBaseInit(TIM4, &timerbase_struct);

/* Configure Timer3 as master. Use external trigger to start Timer3 */

TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Enable);

TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);

TIM_SelectInputTrigger(TIM3, TIM_TS_ETRF);

TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Trigger);

/* Configure Timer4 as slave */

TIM_SelectInputTrigger(TIM4, TIM_TS_ITR2);

TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Trigger);

}

Posted on November 16, 2015 at 14:30

I can't explain the 30 to 35ms, but are you aware of the fact that the prescaler is not updated until an Update Event happens?

JW

ArturasV
Senior
Posted on November 16, 2015 at 14:55

Yes i am aware of that. It is for the first launch. After that, the delay between timers is about 1.2ms, which is still way too big. And another strange with i've noticed: do you see any problems because with code? because after i give an external trigger to the pin and i stop with breakpoint in the code, i see that TIM4->CNT  > TIM3->CNT . Isn't it strange, considering that i am triggering TIM3 with external pulse, and enable of TIM3 should enable TIM4? 

mikael239955_stm1_st
Associate III
Posted on November 16, 2015 at 17:35

AN2592 and AN4013 sektion 3.1.

Then be aware of  various spelling errors that make various appnotes not working so you have to figure out by actual testing.

I dont do SPL or HAL but for TIM4 you have an additional divider:  

 timer_input_struct.TIM_ICPrescaler = TIM_ICPSC_DIV1;  

>For some reason, in my RM version for F4 i don't have the tables with Timers ITR which i found in RM

> i dont quite understand from RM which Timers can work as masters and which ones can work as slaves.

 

With ST you constantly have to refer to multiple documents, it's rare if you can get away with only one.Depends on project

size and number of peripherals used but in general. For the actual chained workings you have to look closely to several bit

fields such as ETP,ETF, TS, MMS and SMS bits etc, and all the input divider chain on all timers used.
ArturasV
Senior
Posted on November 18, 2015 at 13:27

Thank you tjerneld.mikael, but the error i get is still too big. Im aware of those documents which you linked me to, i have read them many times. I am able to start the Timers, but the delay between them is always a few hundred timer ticks at least. Don't know if it has to be like this or this is just my code.

ArturasV
Senior
Posted on November 18, 2015 at 15:41

Okey, so now i have tried to do things a little bit different. I set up Timer3 to trigger from external pulse (rising edge) , and configured Timer4 and Timer5 both to be triggered from Timer3 UPDATE event. Still, the difference i am seeing between two Timers (TM4 and TM5) is varying from 1.5 to 2.5ms! Considering the fact that Timers are running 0.1ms ticks (Timers psc = 4200-1) this is absolutely inappropriate. I am starting to think, maybe this could have something to do with the debugger and IDE? I am using Atollic Studio. My code is below:

void timers_config(void)

{

/* Timer 3 Configuration */

timerbase_struct.TIM_Prescaler = 4200-1;

timerbase_struct.TIM_Period = 60000;

timerbase_struct.TIM_CounterMode = TIM_CounterMode_Up;

timerbase_struct.TIM_ClockDivision = TIM_CKD_DIV1;

timerbase_struct.TIM_RepetitionCounter = 0x00;

TIM_TimeBaseInit(TIM3, &timerbase_struct);

/* Configure Timer3 as master. Use external trigger to start Timer3 */

TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Update);

TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);

TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Trigger);

TIM_SelectInputTrigger(TIM3, TIM_TS_ETRF);

TIM_ETRConfig(TIM3, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x0F);

/* Timer 4 Configuration */

timerbase_struct.TIM_Prescaler = 4200-1;

timerbase_struct.TIM_Period = 30000; // 10k tick = 1s

timerbase_struct.TIM_CounterMode = TIM_CounterMode_Up;

timerbase_struct.TIM_ClockDivision = TIM_CKD_DIV1;

timerbase_struct.TIM_RepetitionCounter = 0x00;

TIM_TimeBaseInit(TIM4, &timerbase_struct);

/* Timer 5 Configuration */

timerbase_struct.TIM_Prescaler = 4200-1;

timerbase_struct.TIM_Period = 30000; // 10k tick = 1s

timerbase_struct.TIM_CounterMode = TIM_CounterMode_Up;

timerbase_struct.TIM_ClockDivision = TIM_CKD_DIV1;

timerbase_struct.TIM_RepetitionCounter = 0x00;

TIM_TimeBaseInit(TIM5, &timerbase_struct);

/* Configure Timer4 as slave */

TIM_SelectInputTrigger(TIM4, TIM_TS_ITR2);

TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Trigger);

/* Configure Timer5 as slave */

TIM_SelectInputTrigger(TIM5, TIM_TS_ITR1);

TIM_SelectSlaveMode(TIM5, TIM_SlaveMode_Trigger);

}

ArturasV
Senior
Posted on November 18, 2015 at 17:31

The topic can be closed, i found the issue. It was problems with the debugger, i wasn't stopping Timers when MCU was halted.