Time Base Generation
This is most basic use of a timer. In this mode of operation, we will have to program the timer as such that it’ll periodically generate timed events. For this purpose we can use any timer but I recommend using either GP timers or basic timer (if any). There is no specific reason for this recommendation. It is just my way of using STM32 timers – use things that have been designed for their purposes.
For making time base generators we need to follow a few steps and the overall thing is very easy. We will use interrupt-based method. First we need to determine which timer we will be using and what should be the frequency of the timer interrupt. We, then, need to calculate the values for the prescaler (PSC), the auto-reload register (ARR) and the repetition counter (RCR) (if any). Repetition counters are available only in advanced timers only. We can use the following formula for determining interrupt rate:
TIMx clock is dependent on APB bus clock.
Finally we will be enabling timer interrupts and the counter module itself.
Sometime along its path in the world of embedded systems, MikroElektronika (MikroE), a well-reputed microcontroller-based hardware and software solution provider, developed a free tool called Timer Calculator. This tool made life easy. We can use it to generate codes necessary for timer interrupts. It generate codes for MikroC, MikroBasic or MikroPascal. Originally Timer Calculator used support PIC and AVR platforms only but recently after unveiling MikroE ARM compilers, ARM platforms were incorporated with it. If we have fairly some sound idea of how things are working inside a STM32, we can avoid all the time-consuming, tiring silly calculations and use it to complete your job easily. We just need to select the STM32 family, MCU clock and desired interrupt rate either in terms of time or in terms of frequency. There are also some preset code examples than can also be used to get a head start.
Timer Calculator can be downloaded from here:
In terms of registers we just need to deal with the following registers only when we need to generate time-bases. I will not explain them in details as their coding will do that.
MikroE Timer Calculator Example
There’s nothing to say about this example as the software says for itself. We just need to the stuffs as marked in the image below. In this example two LEDs connected to GPIOC pin 6 and 7 will toggle logic states every 500ms. Pin C7 LED flashes due to timer 6 update interrupt and pin C6 LED blinks due one main loop execution. After every interrupt, interrupt flags in the timer status registers need to be cleared.
TIM6_SR.UIF = 0;
GPIOC_ODRbits.ODR7 ^= 1;
GPIOC_ODRbits.ODR6 ^= 1;
(_GPIO_PINMASK_6 | _GPIO_PINMASK_7),
(_GPIO_CFG_MODE_OUTPUT | _GPIO_CFG_SPEED_MAX | _GPIO_CFG_OTYPE_PP));
GPIOC_ODRbits.ODR6 = 0;
GPIOC_ODRbits.ODR7 = 0;
RCC_APB1ENR.TIM6EN = 1;
TIM6_CR1.CEN = 0;
TIM6_PSC = 575;
TIM6_ARR = 62499;
TIM6_DIER.UIE = 1;
TIM6_CR1.CEN = 1;
Demo video link: https://www.youtube.com/watch?v=L3TVU7BGK9s.
There are some ignorable limitations of the MikroE Timer Calculator software. For instance it doesn’t support advance timers but I don’t find it as a problem. You can use any other timer like Timer 4 for instance, generated codes for it and then renumber/rename the registers. Another reason for which I’m not bothered by this is due to the fact that advance timers are meant for dedicated advanced tasks and not for silly time-keeping.