Electronic – STM32F4 TIM2 timer, getting to 1 second

armccortex-mcortex-m4timer

I'm learning a bit about general purpose timers on my STM32F4Discovery board, and would like to know how I can configure the timer to invoke a timer interrupt each second, or at least have the auto-reload value reset to 0 every 1 second.

I know the MCU runs at 168MHz, and I'm using the internal clock as the TIM2 clock source. I would like to understand better how I can calculate the appropriate prescale value, period and clock division to achieve 1 sec.

TIM_HandleTypeDef timeBase;
timeBase.Instance = TIM2;
timeBase.Init.Prescaler = 0;
timeBase.Init.CounterMode = TIM_COUNTERMODE_UP;
timeBase.Init.Period = 168000000; // Hypothetical value (Period cannot be greater than 65535)
timeBase.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
HAL_TIM_Base_Init(&timeBase);

Am I correct in saying that the above, with a prescaler of 0, period of 168000000 and clock division of 1 will cause a the timer auto-reload value to reset to 0 each 1 second?

Now, the Period has a max value of 0xFFFF (65535), so to me that means I need to manipulate the prescaler value, and period to achieve a 1 second auto-reload value reset.

Is there a formula for doing this?

Best Answer

You have two problems. The first is that the MCU runs at 168MHz if it has been set up that way, and your compiler may not do that by default. Setting up the clock is a bit arcane. ST provides an excel-based tool to help you create a setup file, and then the file needs to be put in the correct place and some other files need to be edited.
enter image description here

I recommend this site as a place to get all the relevant info. There is an ST page with instructions, but it isn't as clear as some of the other tutorials.

If you do this, the APB1 bus, the one that TIM2 is on, will run at 42MHz max, giving you an 84MHz TIM2 clock (it's doubled by PLL). If you need faster than that, you must use one of the timers on APB2, which goes twice as fast. Note that that bus doesn't have any 32-bit timers.

enter image description here

The second issue is, as you said, you exceeded a maximum value. Yes, you need to play with the two values. If you divide your clock by (42000-1) with the prescalar to give you a 2 kHz time base, and then set the period to (2000-1), there's your 1 second interval.

Of course, you must TURN ON THE CLOCK to the TIM2 peripheral, and then enable TIM2, or nothing will work.