Timers of MSP430

In the last tutorial, we had a look at configuring clocks or rather internal clocks of the MSP430. Since you are now at a stage where you can configure clocks on your own, we can use them to access various functionality of the MSP430. All of the major functions such as the ADC, timers, e.t.c rely upon the clock or the clock speed at which the microcontroller is functioning. Timers of any microcontroller are special registers that increment or decrement their value automatically. They are an integral part of the microcontroller and are used in almost every project from basic to complicated one. A good feature of the timers of the MSP430 you can use them to achieve real time clock i.e a delay of exactly 1 sec, provided you use the 32.768kHz crystal provided to you with the Launchpad.

timer

Let’s move onto the technical specification of the timer. If you have referred to the user guide of the msp430 you must have founded out there are two types of timer mainly ‘TIMERA’ and TIMERB’. Important point to note here is that none of the value device have the functionality of TIMERB. So overall, in a msp430 which I will be using will have only one timer called as TIMERA which is a 16 bit timer (counts from 0 to 65535). If you are eager to know about the ‘TIMERB’ functionality you can learn about the ‘TIMERA’ from here and refer to the user guide for apt information.

Before we get into the register part, let us have a look at the modes of the timer. Timer of MSP430 can operate in three modes. To use which mode will depend entirely on your application.

  1. Up mode: – In this mode the timer counts up to a pre specified value and then rolls over to zero. It’s up to you to decide till which point you want the timer to run
  2. Continuous mode: – In this mode the timer counts from 0 to 65535 and then roles over to zero.
  3. Up/Down mode: – In this mode the timer first counts up to a pre specified value but instead of rolling over to zero it turns around and counts to zero.

Moreover, we can also make the use of timer as a counter by setting specified points known by compare/capture register. The functionality of these register we will look in upcoming tutorial.

Let’s head over to our mission statement for today. In the blinking led program which we did while learning the GPIO of the controller, we used manual loops to provide delay. Our statement remains the same but this time we will specify the delay and use timers to do it.

The below image shows the bits of the register to control the timer. It mentions about the mode and the frequency at which the timer will run.

register

Above information is enough for you to learn about the register TA0CTL for timer control, but if you still have any doubt, you can comment below and I will try to answer your queries as soon as possible.

As you can see in the image, it ask us to select the clock source. For now we will be using the internal DCO i.e SMCLK, but in the near future we will see how we can generate longer delay accurately with use of auxiliary and other clocks.

I will be running the controller at 1 MHz with a prescalar of 8. However it’s your wish if you want to use prescalar or not.

The above was the control register. Apart from the control register there are two more register. One is the ‘TACCR0’ register where we specified the maximum value of the timer. Remember the up or up/down mode we talked about which mentioned about the pre specified value. The pre-specified value is decided by the value of this register. Now the question is how to calculate that value. The value depends upon the delay (in seconds) you want to generate and the clock frequency of the timer. Remember it’s the clock frequency of the timer and not the clock frequency of the controller. The value is given by

TIMER VALUE=(Delay*frequency)-1

Where delay is in seconds and frequency in Hz.

For example if you are running your microcontroller at 1MHz, and for timers you are using a prescalar of 8 and want a delay of 0.5sec, the value to be loaded in the register will be given by ((0.5*1*10^6)/8)-1 which will give you a value of 62499.

Another important register is the TAR register. If you read the value of the register at any point of time it will report the current value of the counter. For this tutorial we won’t be using this register.

Let’s move onto the coding part. As usual start CCS and create a new empty project (with main.c) based on the device on your Launchpad. In mine case its msp430g2553. You will already find the basic code written which will include the main function and the code to stop the watchdog timer. We will first star by calibrating our DCO and the initializing the timer and then the ports and then infinite loop.

In the last tutorial we saw how to calibrate the DCO. Let’s say you want to run it at exact 1 MHz Although you could look up to the table and set the value of the bits accordingly, but TI has provided us direct way to calibrate the DCO to run at 1 MHz It can simply be done by these two instructions.

BCSCTL1 = CALBC1_1MHZ;
DCOCTL = CALDCO_1MHZ;

Now that was quite easy. Normally, I prefer to use up mode as it is quite convenient and in this tutorial also I will be using up mode only. To use up mode we need a value till which the timer will run. From the above example, we saw that for a delay of 0.5sec with timer running at a one eight of 1 MHz, the value came out to be 62499. We will be use the same value to load in the register TACCR0. The next part is to configure the control register. There are two ways, one is to use normal hexadecimal configuration, but we will use the other way which is to use TI header file for configuring the register. It’s pretty easy to do that way. For our application the timer clock source will be SMCLK, hence the value of TASSEL will be 10. For up mode, the value of MC will be 01, value of ID will be 11 for presclar of 8. Rest all will be 0. An easy way to configure the register is by giving the instruction

TA0CTL |= TASSEL_2|ID_3|MC_1|TACLR;

Everything is pretty clear except the value after the underscore. Well this value is the decimal equivalent of bits given in binary. So 10 is 2, 11 is 3 and 01 is 1. Also TACLR which is to rest the timer has been declared as 0. The next step will be to declare the port 1 as output and set it to low initially which is quite easy.

Now comes the main part. Whenever the timer counts up to the value specified in the TACCR0 register, the TAR register  rolls over to zero. When it rolls over to zero, it sets the TAIFG(bit 0 of TA0CTL) register as 1. Our job is to monitor that bit. As soon as it goes high, we toggle the state of the led and then reset the bit manually. Therefore we used a ‘if condition’ to monitor the status using bitwise operator and then toggle the state and reset the flag. Here is the complete code along with the diagram

 

#include <msp430g2553.h>
/*
 * main.c
 */
int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer
    BCSCTL1 = CALBC1_1MHZ;   //Set DCO to 1Mhz
    DCOCTL = CALDCO_1MHZ;    //Set DCO for 1Mhz
    TACCR0 = 62499;   //Timer Count for value 0.5sec
    TA0CTL |= TASSEL_2+ID_3+MC_1+TACLR;  //using SMCLK with prescalr of 8 in upmode.
    P1DIR |= 0x01;  //Make P1.0 as output
    P1OUT=0x00;   //make p1.0 low
    while(1)
    {
    	if((TA0CTL&TAIFG)!=0){    //monitor the flag status
    	P1OUT^=0x01;        //toggle the led
    	TA0CTL&=~(TAIFG);   //clear the flag
    	}
    }
	return 0;
}

circuit_diagram

Well this was a straight forward way to use timer, monitoring every time the flag. But the better way to do it is to use interrupts which will automatically monitor the flag and when it sets high, it will called the interrupt routine vector, and will automatically clear the flag. More on this in the upcoming tutorial.

Bookmark the permalink.

4 Comments

  1. Do we really need to set the DCO for MSP430 here. By default it uses the same with 1.1MHz.

  2. Actually, it’not exactly 1.1 Mhz. Referring to the datasheet, going by their calculation it comes out to be around 1.1Mhz or rather closer to 1.2 Mhz. Instead of using register configuration to set frequency you can use predefined headers to set the same.

  3. I tried it on my board! With out configuring the clock I was able to generate 0.5 sec.

  4. How did you measure the 0.5 second delay. Did you connect your output pin to an oscilloscope. There is not much difference in between 1.1 Mhz and 1.0 Mhz such that it effects the timer delay value. However, over the time the drift may be accountable. therefore, i request you to measure the delay when the board is set to 1Mhz and share with us here

Leave a Reply

Your email address will not be published. Required fields are marked *