MSP430
|
Modified: |
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 onmov.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