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 hardware timer. The basic function of a (hardware) 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 resolution (number of bits) than others and some can be used for more than just keeping track of time.
We'll be using one of the basic timers:
TIM6. 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 670 - Reference Manual
Its registers are documented in:
Section 22.4.9 TIM6/TIM7 register map - Page 682 - 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).
TIM6 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 increases at a frequency of
apb1 / (psc + 1)
times per second, where
apb1 is the frequency of the APB1 clock and
psc is the value of the