MSP430
Getting Started

Modified
© Ray Wisman

CCS

File | New does not show the CCS entry, probably need to View | C/C++ first.

Resources

Timers - http://www.ccs.neu.edu/home/noubir/Courses/SWARM/S09/slides/msp430-clocks-timers.pdf

Timers/Counters

Timers are driven by a clock signal, commonly incrementing (decrementing) a counter on each clock. When the counter reaches some predefined value (e.g. 0), the timer can generate an interrupt. The result is a reasonably accurate time base for executing functionality such as maintaining a reference clock (seconds, minutes, etc.) or performing some operation on a regular basis (blink a LED every second).

The MSP430 has many options for creating timers, we will limit ourselves to a simple one that illustrates the basic concepts.

CCTL0

Control register for counter 0. Interrupts are enabled by writing a 1 into bit 4 of this register.

CCR0

Holds the count value, 12000 is used because the clock operates at approximately 12KHz and we want to toggle the LEDs at approximately at one second intervals. With interrupts enable, an interrupt is generated when the count reaches 12000.

The counter is automatically reset to 0.

TACTL

Timer A control register.

TASSEL_1 = 01 in bits 9-8, selects timer A source clock as ACLK, 12KHz.

MC_1 = 01 in bits 5-4, sets UP count mode, counting up to the value in CCR0 and generating an interrupt if enabled.

One important point is that timers run asynchronously to the CPU clock, which can be turned off and turned on when an interrupt occurs.

SR/R2

Status register.

CPUOFF = 1 in bit 4 turns off the CPU until interrupt occurs.

GIE = 1 in bit 3 enables global interrupts (same as EINT instruction).

#include <msp430g2231.h>

void main(void) {
	WDTCTL = WDTPW + WDTHOLD; 			// Stop watchdog timer
	P1DIR |= 0x41; 					// Set P1.0 and P1.6 to output direction
	P1OUT &= 0xbf; 					// Set the red LED on
	P1OUT |= 0x01; 					// Set the green LED off

	CCR0 = 12000;					// Count limit
	CCTL0 = 0x10;					// Enable counter interrupts, bit 4=1
	TACTL = TASSEL_1 + MC_1; 			// Timer A with ACLK, count UP

	__bis_SR_register(LPM0_bits + GIE); 		// LPM0 (low power mode) with interrupts enabled
} 

#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void) {				// Timer A0 interrupt service routine
	P1OUT ^= 0x41;					// Toggle red/green LEDs
}	
 	.cdecls C,LIST,  "msp430g2231.h"
      .text                           ; Progam Start
main  mov.w   #0280h,SP               ; Initialize stackpointer
      mov.w   #WDTPW+WDTHOLD,&WDTCTL  ; Stop WDT
      bis.b   #01000001b,&P1DIR       ; P1.0 and P1.6 output
      bic.b   #00000001b,&P1OUT       ; Set green LED off
      bis.b   #01000000b,&P1OUT       ; Set red LED on
      mov.w   #10h,&CCTL0             ; CCR0 interrupt enabled, bit 4 = 1
      mov.w   #12000,&CCR0            ; Count 12000 to CCR0
      mov.w   #TASSEL_1+MC_1,&TACTL   ; ACLK source (~12KHz), UP mode (count up to CCR0 value)
						
      bis.w   #CPUOFF+GIE,SR          ; CPU off, interrupts enabled

TA0   xor.b   #01000001b,&P1OUT       ; Toggle P1.0 and P1.6
      reti                            		

;     Interrupt Vectors
      .sect   ".reset"                ; MSP430 RESET Vector
      .short  main                    ;
      .sect   ".int09"                ; Timer_A0 Vector
      .short  TA0                 
      .end