picspalsandgals

University of Washington Electrical Engineering Blog

In the last post we managed to toggle the MSP’s LEDs using a power hungry active waiting loop.  This time let’s try to do it with interrupts instead.  The MSP has a low power clock called the ACLK.  We’re going to use it to count to a value, then trigger an interrupt that toggles the LED state.  This application is a little less clear than the previous one due to the cryptic register names, so I’ve done my best to comment it clearly.

#include “io430.h”

#include “in430.h”

int main( void )

{

WDTCTL = WDTPW + WDTHOLD;                        //Set up the watch dog timer

P1DIR |=  0x03;                                            //Set the LED’s to output

BCSCTL3 |= LFXT1S_2;                              //Set the ACLK to a low power oscillator

TACCTL0 = CCIE;                                       //Enable Interrupts on timer_A

TACCR0 = 1000;                                          //Set the value the timer counts up to

TACTL = MC_1+TASSEL_1;                       //Tell timer_A to increment each time ACLK ticks

__bis_SR_register(GIE+LPM3_bits);           //Enable Global Interrupts, and go into Low pwoer mode

}

#pragma vector=TIMERA0_VECTOR          //Set the interrupt to trigger the following function

__interrupt void Timer_A (void)

{

P1OUT ^= 0x03;                                           //toggle the LEDs (Finally!)

}

 

The code seems a little scary to look at, but it comes down to a fairly basic plan: have a counter (timer_A) increment each time a clock (ACLK) ticks, then once it counts to 1000 toggle the LEDs.

Now admittedly, there are a couple things I haven’t figured out about this program, and am going to have to look into further. First, embedded applications usually have a while (1) loop that contains their main processing, but that’s not the case for this program.  This would imply that the program executes once then resets.  But, if this is the case how does the timer keep track of what its currently counted to?  My guess is that since there is only a soft reboot (the power doesn’t cycle), there is a low level register that keeps track of the timer regardless of the high level application running.  My second question is with the interrupt syntax.  After spending a significant amount of time looking over this code snippet, I can’t tell what exactly the “#pragma vector=TIMERA0_VECTOR” line does.  It appears that it sets a variable “vector” to a specific value, but what exactly that does to connect the interrupt to the specified function is a mystery.  Hopefully more playing with the code will reveal what going on.

 

I mentioned that this version of the blink code should be more efficient power wise.  We connected a 1 ohm resistor in series with our supply to approximate the current drawn by the MSP.  When running the version of the blink code from last time (with the active for loop) we measured a current draw of 2.2 mA, while the timer interrupt version required only 1.7 mA.  This seems like a small change, but in the world of embedded systems a draw of .5mA can make or break a system.  Note that this is a difference between low power modes zero and four. We initially heard that the MSP has closer to twenty different low power modes, but so far we have only been able to gain access to LPM0 through LPM4

 

Next on the list is configuring and using the MSP’s radio to start communicating between devices!

Leave a comment