I hope that, by now, I have convinced you that
for loop delays are a poor way
to implement delays.
Now, we'll implement delays using a "timer". The basic function of a timer is ... to keep precise track of time. A timer is yet another peripheral that's available to the microcontroller thus it can be controlled using registers.
The microcontroller we are using has several (in fact, more than 10) timers of different kinds (basic, general purpose, and advanced timers) available to it. Some timers have more "precision" than others and some can be used for more than just keeping track of time.
We'll be using one of the "basic" timers:
TIM7. This is one of the simplest
timers available in our microcontroller. The documentation for basic timers is
in the following section:
Section 22 Timers - Page 674 - Reference Manual
Its registers are documented in:
Section 22.4.9 TIM6/TIM7 register map - Page 686 - Reference Manual
The registers we'll be using in this section are:
SR, the status register.
EGR, the event generation register.
CNT, the counter register.
PSC, the prescaler register.
ARR, the autoreload register.
We'll be using the timer as a "one-shot" timer. It will sort of work like an alarm clock. We'll set the timer to "go off" after some amount of time and then we'll wait until the timer "goes off". The documentation refers to this mode of operation as "one pulse mode".
Here's a description of how a basic timer works when configured in one pulse mode:
- The counter is enabled by the user (
CR1.CEN = 1).
CNTregister resets its value to zero and, on each "tick", its value gets incremented by one.
- Once the
CNTregister has reached the value of the
ARRregister, the counter will be disabled by hardware (
CR1.CEN = 0) and an "update" event will be raised (
SR.UIF = 1).
TIM7 is driven by the APB1 clock, whose frequency doesn't have to necessarily
match the processor frequency. That is, the APB1 clock could be running faster
or slower. The default, however, is that both APB1 and the processor are clocked
at 8 MHz.
The "tick" mentioned in the functional description of the one pulse mode is
not the same as one tick of the APB1 clock. The
CNT register usually works
at a slower rate because this register actually operates at a frequency of
APB1_CLOCK / (PSC + 1), where
PSC is the value of the prescaler register