16 Timer
16 Timer
1 Introduction
1
signal, in which case the processor will be able to execute 2.8 ∗ 109 instructions
per second. You might have heard of things like overclocking in which people
(mostly game enthusiasts) try to gain better performance by increasing the clock
speed (Ref: http://en.wikipedia.org/wiki/Overclocking ). The power consumed
by the processor increases as its clock speed is increased - this has signicant
implications in battery-powered systems (say mobile phones).
Things are even more complex in the case of a microcontroller because the
controller integrates a processing engine with lots of other peripherals - each
of these peripherals will need clocks of varying frequencies. In order to save
power, the microcontroller should be able to shut down the clocks to each of
the peripherals independently (thereby powering down that peripheral). In a
complex controller like the ARM, you will nd a very large number of pages in
the manual describing the working of the clock subsystem in detail !
1
It is easy to write a blinking LED program using what is called a delay loop:
#include <msp430.h>
#define LED1 BIT0
#define TOGGLE_LED1 (P1OUT ^= LED1)
void delay()
{
unsigned int i = 0;
while(++i < 30000);
}
main()
{
P1OUT = 0;
P1DIR = 1;
while(1) {
TOGGLE_LED1;
delay();
}
1 The MSP430 datasheet has only 13 pages describing the working of the basic clock
module - page 273 to 286
2
}
Notice how the RED led blinks when you run this code! There are a few points
to discuss regarding this program:
2. The 3 cycles average gure is also not very accurate - we will have to
refer the datasheet and nd out how many cycles each instruction takes
to arrive at a more accurate gure.
2 There are a few other issues concerning compiler code generation which we shall not
discuss at this point
3
These patterns are useful for manipulating individual bits of peripheral reg-
isters. For example, the statement:
will set the D2'th bit of P1OUT (thereby making pin P1.2 go logic HIGH if it is
congured as an output pin). Similarly, the statement (remember, ^ represents
the bitwise XOR operation):
will result in the D0'th bit of P1OUT toggling its value (if current value is 1, it
becomes 0, if it is 0, it becomes 1). Similarly, the statement:
will result in the D2'th bit of P1OUT becoming equal to 0, with no other
bits aected. We should always use these symbolic names when manipulating
individual bits.
P1OUT ^= LED1
is equiavalent to:
which has the eect of toggling P1.0 (the pin to which LED1 of the launchpad
board is connected to).
4 Timer A
4
4.1 What does a timer really do?
The timer is conceptually a simple device. Here is how it works: every timer
has a register internal to it which is capable of holding an 8/16 bit value. The
timer takes as input a clock signal. Suppose the frequency of this clock signal
is 100Hz. Once the timer starts running, the value stored in the internal 8/16
bit register will get incremented every cycle of the clock signal. That is, if the
value of the timer register was 0 at the moment the timer got started, after 1
second, its value will become 100 (if the clock frequency is 100Hz).
Now, here comes the really important point: you have to execute certain
instructions in software to start the timer - but once it starts running, the count
will get incremented once every clock cycle - the microcontroller can keep on
executing the instructions in your program and the timer will happily run in
parallel!
The key word here is in parallel. Make sure that you have understood
this properly - none of the discussion below will make sense if you do not get
this idea. The microcontroller keeps running your code and the timer keeps on
ticking independently, in parallel!
How can such a device be useful? Suppose you wish to measure the time
dierence between an I/O pin going low-to-high and then high-to-low. Here is
a recipe for doing this:
1. When you detect the input pin going low-to-high, set the timer register
to zero and issue an instruction to start the timer.
2. Note the value of the timer register when the input pin goes high-to-low.
Store this in a variable.
Suppose the value of this variable is 10 - this means that 10 cycles of the timer's
input clock had elapsed between the transitions on the I/O pin. Assuming that
the clock frequency is 100Hz (which means clock period is 10 milli seconds), the
total time dierence between the I/O pin transitions is:
5
uses an internal digitally controlled oscillator (DCO) as a clock source - with
the DCO frequency set to a value between 0.8 to 1.5MHz. The problem is that
we do not know what the precise value is. In some applications, this may not
really be a problem. But if you really wish to get precise timing, you will have
to think of choosing a clock source other than the internal DCO .
3
On most microcontrollers, you have an option to use an external component
(a quartz crystal; reference: http://en.wikipedia.org/wiki/Crystal_oscillator)
to provide a stable clock signal with precisely known frequency. The MSP430G2231
microcontroller too has this option (you might have noticed that the launchpad
kit comes with a watch crystal which may be soldered on to the board if
required), but we shall not explore it at the moment .
4
Refer page 372 of the datasheet - you will see a description of this 16 bit register
on that page. The page begins with two table rows with each row containing
names like IDx, MCx, TACLR etc.
What does the name IDx represent? It is the name given to two bits of
this register, bits 6 and 7. Similarly, what does the name TACLR represent? It
is a symbolic name given to bit 2 of TACTL. Because each bit of the register has
some special purpose (except the few unused bits), it makes sense to give specic
names to them so that you can talk about them without actually mentioning
the bit numbers. Note that these names are just a notation used for convenience
sake.
You will see something like this written below TACLR (and all the other
bits):
3 It is possible to calibrate the internal DCO to a certain frequency. But once again,
there are other issues. The DCO frequency will change with temperature ... the only way to
achieve a stable frequency over a range of temperatures is to use an external crystal as the
clock source.
4 Some more info, for those who are interested: http://mspsci.blogspot.com/2010/06/crystal-
timers.html
6
rw-(0)
This says that the bit is read-write - you can read it's value, you can also write
to it. The (0) indicates the fact that the default power-up value of the bit is 0.
We shall now look at what some of these bits are actually used for!
Let's focus on the bits TASSELx (Timer-A clock source select) - bit numbers 8
and 9.
There are multiple sources for the clock signal to the timer on the msp430
processor. A discussion of the dierence between these sources is beyond our
scope at the moment. You need to understand the following:
1. You can choose the clock for timer-A from 4 dierent sources
2. This selection is done by using one of the four combinations of values: 00,
01, 10, 11 as the value of the TASSELx bits (bits 8 and 9).
2. Continuous mode: The timer increments the value of the internal count
register from 0, 1, 2, 3, ... 0x (65535) - one increment per clock cycle.
Once the maximum count of 0x is reached, the count resets to 0 and
the process restarts. So the count sequence is: 0, 1, 2, 3, .... 0xfe, 0x,
0, 1, 2, 3, .....
7
3. Up mode: The timer counts from 0 to the value specied in a special
register called TACCR0. Once the value of the count register becomes
equal to the value in TACCR0, the counter resets to 0 and the process
restarts.
4. Up/Down mode: The timer counts from 0 to the value specied in a special
register, TACCR0. Once the value of the count register becomes equal to
the value in TACCR0, instead of resetting to 0, the timer starts counting
down. For example, if the value in TACCR0 is 5, the count sequence is:
0, 1, 2, 3, 4, 5, 4, 3, 2, 1, 0, 1, 2, 3, ....
Each of the three modes (we ignore the STOP mode) is useful in certain contexts
(we shall not analyse the specic contexts in this lesson). The simplest mode is
Continuous - we will use this mode for writing our LED blinking code. The
MCx bits (bit4 and bit5 of TACTL) decide the operating mode. Refer the
processor manual for the MCx bit combination for each operating mode.
There is an easy way to know when the count resets to zero - simply check
the value of bit 0 of the TACTL register. This bit is called TAIFG (Timer A
Interrupt Flag). TAIFG gets set to 1 when the count becomes 0. If you clear
the TAIFG bit (ie, set its value to 0), it will automatically become set again the
next time the count becomes equal to 0.
You now have enough information to write the blinking LED program. The
rst version of this program used a simple loop to generate a delay. In this
version, you will use Timer-A to generate the required delay.
I will provide you with an outline of the code; you have to replace the
comments in the code with actual C statements and it will start working!
#include <msp430.h>
main()
{
// set P1.0 as output
// make P1.0 go logic HIGH
// Initialize Timer-A; SMCLK; no division, continuous mode
while(1) {
while(/* TAIFG bit is 0 */)
;
// clear TAIFG bit (ie, make it 0)
// Toggle LED on P1.0
}
}
8
I shall elaborate a few points:
1. Keep in mind the fact that the timer, once started, runs in parallel with
your code, in a completely independent way.
2. The basic idea is simple - you start the timer and wait for it to overow
to zero; this overow happens after 65536 clock cycles. If the clock is
1MHz (time period = 1 micro second), the overow will happen in about
65 milli seconds. You know that the timer has reset to 0 when the TAIFG
bit becomes 1 - so you keep on looping as long as the TAIFG bit is zero.
That is what the inner while loop (the loop with empty body) does!
3. Once the timer has reset to 0 (in about 65ms), you can toggle the LED
and once again wait for the next overow! Remember, the timer keeps on
going tick-tick-tick ... while your code is running!
4. The clear TAIFG bit is required because we will know that a count reset
(from 0x to 0) has occurred only when the TAIFG bit changes from 0
to 1. Once this bit becomes set, it is our job to clear it and then wait
again till it becomes set!
Now, go ahead, write the code and enjoy the sight of the LED blinking! (And,
don't forget to push your code to github!).
4.5 Modications
Try to experiment with the code in dierent ways. A fun idea is to vary the
frequency of blinking by changing the IDx bits - try all combinations!
More advanced stu: Read the processor manual and try to use the UP
mode or UP/DOWN mode! Can you blink two LED's (red and green) on the
launchpad board at dierent frequencies?
Another experiment: Compile the rst version of the LED Blinking program
(using delay loop) using the extra option -O3 (gcc -O3 -mmcu=msp430g2231 -
mdisable-watchdog a.c). What do you see when you run the code?
5 Exercises
9
(a) 1KHz
(b) 32768Hz
(c) 14236Hz
(d) 1MHz
(a) 0x823
(b) 0x2f0
(c) 0x0135
4. The register which holds the timer's count can be accessed in your program
- the name of this register (as per the processor manual) is:
(a) TAIV
(b) TACCR1
(c) TAR
(a) P1.0
(b) P1.3
(c) P1.1
8 Ref: http://recursive-labs.com/datasheets/msp430g2x31.pdf
10