01 August 2010

Tutorial 09: Timers

Now that we can configure the clocks in the MSP430, we can use them to drive peripherals.  Peripherals are hardware that may be built into the chip itself or added on by us.  Controlling peripherals is where the microcontroller really comes to its own, and is likely the reason you're learning about the MSP430.  The first peripheral we'll examine is the Timer_A system.

First, note that there is also a Timer_B system available in some devices, which in most respects is just like Timer_A.  None of the value line devices have this system, so if you're eager to use this peripheral in another device, learn about Timer_A and then refer to the Family User's Guide for more information.

A timer is really nothing more than a counting mechanism that is tied to some type of regular interval provided by a clock.  The Timer_A peripheral is what we call a 16-bit timer.  This definition simply means that the timer counts from 0 in binary to 0b1111111111111111, or 0xFFFF in hex, 65,535 in decimal.  Simple enough, and very useful when we know how to manipulate the behavior of the timer.

Timer Modes

There are three modes to operate Timer_A.  Which one we use depends entirely on the application.  The first mode is what we call the continuous mode: Timer_A acts just like a 16-digit, binary odometer; it counts from 0 to 0xFFFF and then "rolls over" to 0 again.  The second mode is called up mode; here, just like in continuous mode, it counts up and rolls over to 0.  This mode, however, lets you choose how high up the timer counts before rolling over.  The third mode, up/down mode, is similar to up mode in that you can program the upper limit.  It differs in that rather than rolling over to 0, it turns around and counts down to 0.  When you would choose to use the different modes may or may not be immediately obvious, so as you peruse articles on this and other sites, take note of how each mode is used when you see them in examples.

In addition to the three ways of counting in Timer_A, there are also a few ways we can make use of the counter.  Timer_A has the ability to set "checkpoints" in its counting (Value Line devices only have two, but other devices have a third).  TI calls these checkpoints Capture/Compare Registers.  The most basic use of these registers is to set values at which the counter flags the processor to do something special.  In fact, one of these registers is what is used to set the upper limit in up and up/down mode.  The other register only flags the processor and allows the timer to keep on counting.  (This is also the behavior of the first register in continuous mode.)

This type of use is the Compare mode of the register; we set a value that is compared to the current count in Timer_A.  If the values are equal, it signals that's the case to the processor.  Capture mode behaves a little differently; the timer waits for some type of signal (often from some sort of input) and then records the current value of the timer in the register without stopping the timer, somewhat like the lap time function of  a stopwatch.

Registers
With so many ways to use Timer_A, you can probably imagine it corresponds to a lot of registers in the MSP430 to use and control the timer.  There are, in fact, at least seven registers used in any device with the Timer_A peripheral.  Let's take a look at each of these in more detail.  In your Family User's Guide, turn to pages 12-20 through 12-23 to see the register maps.

  • TACTL  --  The Timer_A Control Register  is used to set up the link between the timer and a clock and select the mode used.  
    • The TASSELx bits (8 and 9) tell the timer which clock to use as its source. 
    • The clock frequency can be divided by a further factor of 2, 4, or 8 using the IDx bits (6 and 7).  (Note that this is further division to any divisions done from the clock source for the clock itself; you could potentially have a total division of up to 64 from your clock source for this peripheral.)  
    • The MCx bits (4 and 5) select the particular mode for the timer to use.  Note particularly that setting these bits to 0 (the default setting on POR) halts the timer completely.
    • TACLR is bit 2.  If you write a 1 to this bit, it resets the timer.  The MSP430 will automatically reset this bit to zero after resetting the timer.
    • TAIE and TAIFG (bits 0 and 1) control the ability of the timer to trigger interrupts; more on this soon!
  • TAR  --  The Timer_A Register is the actual counter; reading this register reports the current value of the counter.
  • TACCRx  --  The Timer_A Capture/Compare Registers, of which there are two in the value line devices (TACCR0 and TACCR1) are where particular values we want to use are stored.  In compare mode, we write values here where we want the timer to signal an event.  Particularly, TACCR0 is used to store the value to which we want Timer_A to count in up and up/down mode.  In capture mode, the processor will record the value of TAR when the MSP430 is signaled to do so.
  • TACCTLx  --  The Timer_A Capture/Compare Control Registers correspond to the TACCRx registers.  These set the behavior of how the CCR's are used.
    • CMx (bits 14 and 15) change what type(s) of signals tell the timer to perform a capture.
    • CCISx (bits 12 and 13) select where the input signals are taken.
    • SCS and SCCI (bits 11 and 10 respectively) change the synchronicity; the timer normally operates asynchronously to the input signals.  (Yeah, I don't entirely understand this yet either.  Watch for a future post to explain this further.)
    • CAP (bit 8) changes whether capture mode (1) or compare mode (0) is used.
    • OUTMODx (bits 5-7) select various output modes for the CCR's signal when the timer flags a capture or compare event.
    • CCIE and CCIFG (bits 4 and 0) are more interrupts associated with the CCR's.
    • CCI and OUT (bits 3 and 2) are the input and output for the CCR.
    • COV (bit 1) is the capture overflow; this bit is set to 1 if two captures are signaled before the first capture value is able to be read.
  • TAIV  --  The Timer_A Interrupt Vector Register; since there are multiple types of interrupts that can be flagged by Timer_A, this register holds details on what interrupts have been flagged.
    • The only bits used here are bits 1-3 (TAIVx), which show the type of interrupt that has happened, allowing us to take different actions to resolve the different types of interrupts.
There's an awful lot of information to cover to fully explain these registers, unfortunately, so we'll look at some examples of how to use the Timer_A as a means to illustrate what many of these bits do and how to use them.  Before getting to that, though, we'll need to take a look at these interrupts, and that will be the topic of the next post.  Hopefully we've been able to learn a little about the overall function of the Timer_A peripheral.  Shortly we'll be able to put it to use in our MSP430 designs.

8 comments:

Anonymous said...

I really appreciate this blog. Im just getting into using the launchpad which is my first experience with micro controllers, this blog has been an invaluable aid to getting started.

Looking forward to future posts

Unknown said...

I'm glad to hear it's helping! Sometimes I worry that I fall into the same trap of writing in a way that's hard to understand; it's a fine line between obfuscated and accessible! Any time something is unclear (or inccorect) or you have a question, feel free to let us know!

plazma said...

There are 3 ebooks available.
-MSP430 Microcontroller Basics
-Embedded System Design Using the TI MSP430 Series
-Analog and Digital Circuits for Electronic Control System Application; Using TI MSP430 Microcontroller

A book review could be useful so people know what book is good for noods and what is for pros'.

A pdf version is avalable of them if you google for them. Good for review but buy a real copy if you intend to use it.

Anonymous said...

hey man,

i am working on launchpad since last few days. i have been done with all the basic programs.

Using timer UART, i have been successfully able to transfer data from controller to PC but reverse is screwing me since a week or so.

Can you suggest me something to make it possible?
waiting for a positive response.

regards,
qwert

Unknown said...

It's hard to offer help without seeing your code. You might consider putting your code on some file sharing site like gist.github.com and linking it to one of the forums in the community. (Such as http://groups.google.com/group/ti-launchpad or http://www.43oh.com/forum/ )

A guess I can offer is how you're handling the signals from the USB to start recording packets; I'll get more into that when I get around to talking about communication interfaces. NJC has a good start for UART on his blog at http://msp430launchpad.blogspot.com. If you haven't already looked there, it may be of help.

Thanks for asking the question; I don't want to give you the wrong idea that I don't want to help, I'm only trying to encourage use (and growth) of the community at large. For now I'd like to keep the blog posts more on topic, as a way to gather information about one particular idea in one place. Let's talk more about your question in one of the forums when we can see your code!

Unknown said...

Hi, I think this helped me a lot. What I am trying to do is measuring frequency of a signal using timer A and B. I used timer B to give me exact .25sec delay and I counted the number of pulses in timer A. Timer A is configured to take INCLK from one of the ports. This thing worked perfectly fine and gives me correct frequency count in TAR register.

Now I have 2 unknown signals and I want to measure frequency of both of them together. But I dont have idea whether this is possible or not with just 2 timers. Can you suggest me a way to measure frequency of two signals simultaneously?

Thanks,
MDS

Unknown said...

That's an interesting problem. Maybe the best way to approach it is to use the port interrupts to count pulses instead; you could then feasibly have 8 frequency counters.

Use Timer A to set the sample time. When Timer A starts, enable the port interrupts. Each time the port tiggers an interrupt, increment a counter for that particular pin. When Timer A turns off the sampling, you can then use the total counts to get the frequency. Of course, the CPU should be running quickly, and longer sampling times will have less error.

Seems a little rough to me; does anyone else have a more elegant solution?

Anonymous said...

Great blog!! I have been searching everywhere for tutorials. Believe me it is so simple that, tomorrow i have a test, i started today with your blog and i am ready for the exam!!
I am very thankful to you :)