Jump to content
43oh

LPM and Timer interrup


Recommended Posts

You don't have to put the microcontroller into LPM.  For example, the following simple program just counts up for approximately one second and then toggles an LED without using LPM.

// Written for the FR5969
// Uses Timer A1 to toggle the red LED

#include <msp430.h> 

#define    RED_LED_PIN      BIT6      // Red LED is on P4.6
#define    ENABLE_PINS      ~BIT0
#define    ACLK             0x0100
#define    UP               0x0010    // count up mode
#define    COUNT            37000     // count up to this number (~ 1 sec)

/*
 * main.c
 */

int main(void) {
    WDTCTL = WDTPW | WDTHOLD;	      // Stop watchdog timer
    PM5CTL0 = ENABLE_PINS;            // Enable all pins

    TA1CCR0 = COUNT;                  // count this high in timer before setting interrupt flag
    TA1CTL = ACLK | UP;               // start counting up

    P4DIR |= RED_LED_PIN;             // Set the pin as an output
    P4OUT |= RED_LED_PIN;             // Set the pin HIGH

    while(1)
    {
    	if (TA1CTL & TAIFG)           // if the flag has been set (counted up to COUNT)
    	{
    		P4OUT ^= RED_LED_PIN;     // then toggle the red LED
    		TA1CTL &= (~TAIFG);       // reset the interrupt flag
    	}
    }
	
	return 0;

If the clock you are using can operate in a low power mode, and you don't need the CPU for other activities, then it makes sense to use an interrupt service routine and a low power mode to save power, especially in a battery run applicatioin.

Link to post
Share on other sites
unsigned char count=0;
void Delay(){

	TA1CCR0 = 10000;
	TA1CCTL0 = CCIE;
	TA1CTL = TASSEL_2 + MC_1 + ID_3 + TACLR;	// SMCLK, UP mode, div 8
	_bis_SR_register(GIE);
}

int main(void) {
	WDTCTL = WDTPW | WDTHOLD;		// Stop watchdog timer
	BCSCTL1 = CALBC1_1MHZ;                    // Set DCO
	DCOCTL = CALDCO_1MHZ;
	P1DIR |= LED_ALL;
	P1OUT &= ~LED_ALL;

	while (1) {
		if(!(++count % 50)){
			T(1,0);
		}
		else
			Delay();

	}
	
}
#pragma vector = TIMER1_A0_VECTOR
__interrupt void timer1_a0_isr(void){
}

I try to create a 0.5 sec delay using timer interrupt without LPM, but it work. Can you help to fix that?

Thank you!

Link to post
Share on other sites

A timer based delay will not work like you are expecting.

 

First, every 49 times the code loops, you run Delay(). Which resets the timer (TA1CTL = TACLR). So the interrupt never happens.

 

Second, You don't do anything in the interrupt. You don't clear the flag. You don't run any code.

 

Third, your expecting it to block your main code. It won't. It runs in the background, allowing your code to continue. That's why you see most Timer based delays using LPM. LPM stops the main code until the timer interrupt happens, and then starts running the code again.

 

If you want something to work like that, you need a blocking delay (Like running a large "for" loop), or LPM, or using the interrupt to run the code.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...