MSP430 - Low Power Mode

We are getting close to the end of this little exercise, that is, building a simple low power timer.

Now we come to the MSP430 low power modes.

The current consumption of a microcontroller is directly related to its operating clock frequency. Stopping the CPU clock gives the lowest power mode. We want to be able to do this while keeping both the crystal oscillator and the timer module operating.

Some microcontrollers may provide a sleep mode that shuts down the CPU clock. The MCU comes out of sleep mode when an interrupt is detected. The program resumes execution following the SLEEP instruction and returns to sleep mode after executing another SLEEP instruction.

TI MSP430 does things a bit differently. The bit settings which select the requested sleep mode are part of the status register (SR). When an interrupt occurs, the mcu stores away the SR and goes into full operational mode, Active Mode (AM). At the end of the interrupt service routine (ISR) the mcu retrieves the saved SR and returns to the previous low power mode.

Here is a graph of five operating modes showing the resulting reduction in current consumption.




Let us put this into a simple program example:

Code:
// Timer example with Low Power Mode
// 2013.04.28 - MrChips

#include "io430.h"

#define ON 1
#define OFF 0

#define LED1 P1OUT_bit.P0
#define LED2 P1OUT_bit.P6

void delay(unsigned long d)
{
  unsigned long i;
  for (i = 0; i < d; i++);
}

void init(void)
{

  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;

  P1OUT = 0x00;
  P1DIR = 0xFF;

  // Set up 32768Hz crystal
  BCSCTL1 |= DIVA_3;    // divide by 8
  BCSCTL3 |= XCAP_3;    // select 12pF caps

  // initialize Timer0_A
  TA0CCR0 = 512;     // set up terminal count for 1s
  TA0CTL = TASSEL_1 + ID_3 + MC_1; // configure and start timer

  // enable interrupts
  TA0CCTL0_bit.CCIE = 1;   // enable timer interrupts
  __enable_interrupt();    // set GIE in SR
  LPM3;            // select low power mode 3
}

#pragma vector = TIMER0_A0_VECTOR
__interrupt void myTimerISR(void)
{
   LED1 = ON;
   delay(1000);   // flash LED1 for 10ms
   LED1 = OFF;
}

void main( void )
{
  init();
}
Note the changes from the previous program:

1) In the init( ) function, I have added the LPM3 statement which immediately stops the CPU clock and puts it into the lowest power mode. (LPM4 stops the crystal clock hence we don't want that mode.) The timer is setup as before to run for one second.

2) At the end of the one second interval the timer interrupts the mcu and puts it into Active Mode while executing myTimerISR( ).

3) In myTimerISR( ) LED1 will flash for 10ms, just about the shortest time while giving a clearly noticeable flash, the goal being to use as little power as possible. On exiting the ISR, the original settings of the status register (SR) are restored putting the mcu back into the requested low power mode, LPM3.

4) There is nothing else to do in the main( ) program and hence the while(1) infinite loop is no longer necessary and has been deleted.


When operating from a 5V supply the current is slightly over 1μA in the LPM3 mode. With a 3V coin cell the current is less than 1μA.

In the next few posts I will wrap up this little exercise and then I will show you how to use the MSP-EXP430G2 LaunchPad to program a target mcu directly in-circuit on your own protoboard or mcu project thus eliminating the need to move the mcu chip from one socket to another.

Blog entry information

Author
MrChips
Views
12,438
Last update

More entries in General

More entries from MrChips

Share this entry

Top