This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430p2553 and Timers

Hi,

I am preparing for an exam and am having a hard time wrapping my head around timers. I have (simple) working code that alternatively blinks the red and green LED approx. every second using a timer. I am using TASSEL_1 which is the ACLK clock. This clock runs at 32 kHz. I set the timer to be an UP timer and am counting to 200 (well, the interrupt is occurring every 201 counts :o) and this is what confuses me -> the interrupt is happening about every second but the way I got there was with playing with the TACCR0 value until it seemed ok to me. So how do I calculate the correct value for TACCR0 and not just guess it? 

I do realize that this has been explained about 1000 times online but I just cannot seem to understand any of the examples (http://www.msp430launchpad.com/2010/07/timers-and-clocks-and-pwm-oh-my.html, for example, explains it quite well but not for the ACLK). Any help would be greatly appreciated.

Thanking you in advance

Ursus

------------------------------ here is the code

#include <msp430G2553.h>

// just some defines
#define BOOLEAN int
#define FALSE 0
#define TRUE !FALSE

// my two LEDs are on BIT0 and BIT6
#define RED_LED BIT0
#define GREEN_LED BIT6

// set when the RED LED is on
BOOLEAN led_red = FALSE;

/*
 * main.c
 */
int main (void) {

    WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer

    // setup the timer
    TACCTL0 =						// Capture/Compare Control Register
    		CCIE;					// interrupt enable
    TACTL = 						// Timer_A Control Register
    		TASSEL_1 + 				// = ACLK is a 32kHz crystal clock
			MC_1;					// Use the UP mode timer (set up count in TACCRO
	TACCR0 = 200;					// Timer_A will count UP to here

	// setup LEDs
	P1DIR |= RED_LED + GREEN_LED;	// set P1DIR out for RED and GREEN
	P1OUT &= ~RED_LED;				// turn off red
	P1OUT &= ~GREEN_LED;			// turn off green

	// start interrupts
	_enable_interrupts ();

	while (1==1) {
		// do nothing
	}
}

#pragma vector=TIMER0_A0_VECTOR
__interrupt void timer (void) {

	if (led_red == TRUE) {
		led_red = FALSE;
		P1OUT &= ~RED_LED;			// RED OFF
		P1OUT |= GREEN_LED;			// GREEN ON
	} else {
		led_red = TRUE;
		P1OUT |= RED_LED;			// RED ON
		P1OUT &= ~GREEN_LED;		// GREEN OFF
	}
}

  • 32768/201 = 163 times a second, a toggle would then be 81.5Hz
    So something is wrong if you get 1Hz, removed resistor from Launchpad?, not touching the pins with you hand?
  • So I would need to set my count up to 32768 to get a 1 second interrupt then. I'm a software type of guy so I wouldn't know if there was a missing resistor (doesn't look like anything is missing/burt out on the board though) and I am not touching the board at all when it runs... it is on a glass table on the four little rubber circles on the bottom of the board. Maybe the glass table is the problem?
  • >32768 to get a 1 second
    yes.you need to remove resistors that are after the crystal, as I take it you did solder the included crystal?
  • Ursus Schneider said:
    ...which is the ACLK clock. This clock runs at 32 kHz....

     

    Not true! You do not have a 32 kHz crystal and you did not make it oscillate. Your ACLK is at a unknown frequency. 

  • We got given these to use by the university - nope, didn't do any soldering at all. I don't think we are allowed. Is there any other timer I can maybe use to get a 1second interrupt that does not need me to grab a soldering iron?

  • So what do I need to do. Sorry to be so unsure but I found the 32 kHz stuff in the User Manual or Family guide and just assumed :) As I said I am a software guy and just want/need to set a timer interrupt every second. Is there another way to do this?
  • You could set the DCO to 1 MHz by using the 1 MHz Calibrated settings. Thus SMCLK can be 1 MHz.

    Set up Timer as you did. Except select SMCLK instead of ACLK. Set CCR0 to 999 so that it will generate an interrupt every 1000 clocks (counting from 0 to 999 is 1000 counts). And inside your ISR, you can count from 0 to 999 also to make the total count 1000000.
  • if (CALBC1_1MHZ != 0xff){               // skip if erased by mistake
      BCSCTL1 = CALBC1_1MHZ;                // Set DCO to factory calibrate 1MHz  
      DCOCTL = CALDCO_1MHZ;
    }
    
    TA0CTL = TACLR;
    TA0CCR0 = 62500-1;                      // Set Timer to 2Hz
    TA0CCTL0 = CCIE;	                    // interrupt enabled for TA0_0  
    TA0CTL = TASSEL_2 + MC_1 + ID_3;   	    // SMCLK source, uptoccr0, input divider /8
      

    Toggle the LED in the IRQ and they are on for 1/2sec and off for 1/2sec = 1Hz
    To get slower:
    make ISR skip toggle every other time,
    or  DIVS_1 on the SMLK in one of the  BCSCTLx register.

**Attention** This is a public forum