Timer 3 (TIM3) is a general purpose 16 bit timer found on every processor in the STM32 range. It is very flexible with a wide range of features. Many of these features are also present in other STM32 timers so familiarity with TIM3 means that you can get going with any STM32 processor and build knowledge that will be useful for all the other timer types.
In this first article, I will look at the overall structure and features of the TIM3 general purpose timer found on the STM32 family of processors. Follow up articles will look in more detail at the configuration and operation of this timer in a variety of modes to accomplish specific tasks. The idea is to focus on some common requirements and find out how to get the job done without getting bogged down in the finer details. The STM32 timers are all complex and have more options than you are likely to need for the majority of jobs. That can be intimidating and I hope to show that basic use can be quite simple. Configuration is to be done by using the older Standard Peripheral Library. Examples will run on an STM32F4Discovery but should be easily adapted to other boards. Code for the newer HAL drivers may be made available later.
The other articles will be:
1: Generate a regular interrupt timebase using the ARR register
The basis of all the other pieces. This will show how to select the input clock, set the prescaler, use the autoreload register and generate an interrupt on counter reload. I will explain how the internal clock source is derived from the main processor clock and show how to calculate the values for the prescaler and reload registers. A simple interrupt service routine will toggle an LED.
2: Generate a regular interrupt timebase with a Capture/Compare Register
This is very similar to the use of the ARR register except that one of the CCRx channels will be used to generate the interrupt. A key difference here is that the interval between interrupts can (and must) be set at each interrupt. This can be used to produce regular events or each can have its own timing interval. That might be handy when servicing sensors or driving stepper motors.
3: Generate a regular pulse train on one or more of the timer output channels
The CCRx registers can be set to directly produce a regular clock signal on one of the output pins. The outputs are square waves. If more than one channel is used, all have the same frequency but each can have a specific phase relationship to the others.
4: Generate multiple PWM signal on timer output channels
Once the output pins are set up for PWM, they will cheerfully continue to output the signal for as long as you like. The duty cycle of the signal can be changed at any time.
The STM32 timers
There is a great variety of timers on the STM32 processors. ST application note AN4013 has a table showing what is available across the range.
You can see that only TIM3 and TIM6 can be found across the entire range. Since TIM3 has a greater range of features, this is the one I have chosen for this series of articles on the configuration and use of timers on the STM32.
TIM3 is a general purpose timer that can be used for multiple channels of output compare, input capture and pulse generation. It is also good for pulse counting when interfacing with sensors such as quadrature shaft encoders and Hall effect sensors in motor control. Flexible PWM generation, including multi-phase brushless and brushed drive methods are catered for. Integration with the DMA facilities of the chip makes possible sophisticated operation without placing a great demand on the processor. External inputs and many interrupt options allow automation of complex tasks.
The main counter in TIM3 has 16 bit resolution. The only 32 bit timers are TIM2 and TIM5 and they are only found on the STM32F2xx and STM32F4xx. This counter can count up, count down and count bidirectionally center aligned. Most timer counters can count in one direction only. For most purposes this is perfectly fine. By allowing the counter to behave in three different modes, some additional features become possible. I will deal with these as they come up.
Associated with the TIM3 counter are four capture/compare channels. Output compare has five modes and allows pulse generation, PWM and timebase generation. Input capture gives you pulse timing and counting options. The PWM output can have four independent channels and each can be edge aligned or centre aligned. Single pulse mode lets you respond to an input stimulus by generating a variable length pulse after a variable delay.
The clock source for the TIM3 timer can come from one of several internal clocks or it can be from an external source. There are also options for synchronising the operation of several timers if needed. Some clock sources can be used simultaneously for synchronisation. External clocks can be prescaled and filtered and you can select the polarity or active edge.
Note that the maximum frequency for the clock source is 84MHz – half the maximum processor clock.
As with all the peripherals in the STM32 family, you must also remember to turn on the peripheral clock. This has nothing to do with the timer features.
The TIM3 timer diagram in the STM32F4 reference manual is a little overwhelming so here is a slightly modified version:
Here I have shaded out the input capture details and some of the input clock information to focus on the basic four channel timer/counter features.
You should be able to see that the clock source is passed to the prescaler, PSC, and then onto the main counter register CNT. Depending on the main counter configuration, the counter register is incremented or decremented at the prescaled clock frequency CK_CNT. At all times, the contents of CNT is compared with the value in the Autoreload Register, ARR. When there is a match between CNT and ARR, the counter will either stop, clear or reverse direction. A match can also generate an interrupt. This is probably the simplest kind of operation and involves no other hardware.
As well as the ARR register, there are four Capture/Compare channels, each with its own register, CCR1, CCR2, CCR3, CCR4. These are also compared continuously with the value in the CNT register and each can be configured for a variety of behaviours when there is a match. Note that a match here does not affect the contents of the CNT register but is can generate an interrupt, trigger some other operation or change an output pin. The output pin can be set, cleared or toggled by the match. Optionally, an interrupt can also be generated on an Output Compare match.
There are six types of events associated with the timers. Each Capture/Compare channel can generate an interrupt or a DMS request in response to a match between the CCR register and the main counter. There is an update event that generates an interrupt on overflow or underflow of the main counter. It will be triggered if the counter matches the reload register contents. Remember that Interrupt service routines must reset the relevant flags or they will be immediately re-entered. Also, they should be marked as extern “C” if linking from C++ code.
Using SysTick to check configuration
There is often a certain amount of mystery about setting up the timers and some way has to be found to verify that the correct values have been calculated. For many simple tasks it is enough to compare with a known timing standard on the processor. For the examples in this series, I generally compare LED outputs with another LED that blinks at a regular rate set by the systick timer. It is then often clear that the timings are way off. It is even possible to detect small off-by-one errors in register values by observing the blinking lights over a period of time to see if they gradually drift out of phase. If you have a musical ear, you can try connecting up a speaker or buzzer and confirming test frequencies that way. A little ingenuity goes a long way toward avoiding the expense of an oscilloscope.
You can find out how to set up SysTick reliably in an earlier article on this site:
This Post Has 2 Comments
how to use timers in stm32f7 discovery, because sample code is not compatible with f7
You will need to find the appropriate peripheral libraries for your device. I still use the older SPL. The newer libraries are quite different. The underlying timer hardware is mostly common across the STM32 series processors though.