Our first peripheral, the humble GPIO, is the most commonly used peripheral. The second most commonly used peripheral is a timer. A microcontroller timer is like a combination stopwatch and kitchen timer: it can tell you how much time has passed, and let you know when a specified amount of time has passed.
At a high level, a timer is just a register that counts up or down automatically. The MSP430 timers are 16-bit registers, so let’s use a 16-bit timer as an example. I’m going to explain a common way that timers are used; this isn’t the only way to use them, but I’ll start here because it’s simple.
A 16-bit timer register starts with a value of 0x0000. When the timer is started, the timer register increments to 1, then 2, then 3, and so on. The timer increments, or ticks, at a precise rate, which you configure. The timer keeps ticking (incrementing) all the way up to the maximum value that can be stored in a 16-bit register, which is 0xFFFF (== 65535 decimal). When the timer ticks again it overflows to zero: the 16-bit register is not big enough to store anything larger than 0xFFFF and so the timer register goes back to 0x0000. It then continues counting up again. This process repeats forever.
Now that you have a rough idea of what a timer is, I’ll explain how to configure it. If you’ve been keeping up with Embedded Software Engineering 101, you’ll remember that it was relatively straightforward to configure a GPIO: a GPIO can be an input or output, it might have a pull-up or pull-down resistor, and maybe it triggers an interrupt.
Timers are more complicated than GPIOs, with many modes and configuration knobs. When configuring a timer you have to tell it:
- How fast to count
- How to count (up, down, or something else!)
- Whether to interrupt or not
Let’s look at each in turn.
How Fast to Count
A timer ticks at a specified rate and you get to set that rate. You need to know a bit more about how a timer works to understand how to configure the timer’s tick rate.
It's About Time
A timer ticks as fast as its input clock. A clock is a digital signal that toggles from 0 to 1 to 0 to 1, forever, at an extremely precise rate. A clock signal looks like this:
The MSP430 we’re using has a main clock signal frequency of 25 megahertz, or 25 MHz. That means the clock signal goes low to high to low again 25 million times each second. The period of a clock signal is the time it takes to repeat itself, as shown in the drawing above. The period is equal to 1/frequency, so for our 25 MHz clock the period = 1/25,000,000 seconds = 0.00000004 seconds, which is 40 nanoseconds, or 40 ns. That is fast.
(Of course that’s nothing compared to your computer’s CPU clock which probably runs at more than 2 GHz. That means the clock toggles more than 2 billion times each second, with a period of 500 picoseconds. This is insanely fast.)
A clock is the literal heartbeat of a microcontroller. A microcontroller’s circuits are synchronized by the clock signal; each time the clock goes from low to high the circuits do their next operation. A clock is like a metronome: it keeps time for a microcontroller.
A microcontroller usually has several clocks, each controlling different parts of the chip, each running at a different speed. You can usually configure a timer to use one of several of the clocks to set the timer’s speed. Additionally, you can usually configure a timer to divide down its input clock to a slower speed if needed.
Example: If you configure a timer to have an input clock of 10000 Hz, and to count up, then the timer will increment 10000 times a second. Each timer tick will be 1/10000 = 0.0001 seconds long, which is 100 microseconds. So if your timer overflows when it reaches 0xFFFF, each overflow will take 65536 ticks, which is 6.5536 seconds (65536 ticks * 0.0001 seconds/tick).
How to Count
Most timers have several ways they can count:
- Up: the timer starts at zero, then counts up until it hits some maximum value.
- The maximum value is stored in a special register called a compare register.
- The maximum value can be the largest value the timer register can hold (like 0xFFFF for our MSP430 timer) or some arbitrary value; it’s whatever value you write into the compare register.
- Down: the timer starts at some value you set and counts down until it reaches zero.
- Up/Down: the timer counts up until it reaches the value in the compare register, and then counts down until it reaches zero.
Timers can also be configured to be one-shot or continuous. In one-shot mode, the counting happens once and then stops once the min/max value is reached. In continuous mode, the counter resets after the min/max value is reached and the counting continues forever.
When a timer reaches the min/max value, the processor can generate an timer interrupt. This interrupt tells you the desired amount of time has passed so your code should do do whatever you want to happen at that time.
I’ve given you a quick, general intro to microcontroller timers. Next time I’ll take a closer look at the MSP430 timers and show you how to configure it. We’ll use the timer to - you guessed it! - blink a light.
This post is part of a series. Check out the complete Embedded Software Engineering 101 series here.