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.

Code for lowest power, 1 adc reading in 1 sec

Genius 3300 points
Other Parts Discussed in Thread: MSP430G2230

I have a battery powered application. Task is to take 1 adc reading in 1 sec & then do few calculations i.e toggle two pins according to adc reading. Circuit should consume lowest power possible. Circuit has one LDO(Iq=500nA) & MSP430 only.
Is below code sequence/settings are best for lowest power:
1. Disable dc generator, disable smclk, internal 12Mhz is used for mclk. Input pull-down all unused pins.
2. Sleep for 1 sec.
3. take adc reading & do some calculations
4. go to step 2.


1. Is it correct approach or should I use 1Mhz clock for this.
2. What is best optimization setting for lowest power, currently I am using Project->Properties->Build->msp430 compiler-> OPtimization:
Opt level- 4 whole program optimization, speed vs size-> 5 speed , Inline hardware multiply->none

Current Code is below

#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A (void)
{
	TA0CTL = MC_0;  /* stop timer */
	__bic_SR_register_on_exit(LPM3_bits);
	_NOP();
}


#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR (void)
{
	__bic_SR_register_on_exit(LPM3_bits);
	_NOP();
}

void adc_read(void)
{
/* enable global int bit */
   	__bis_SR_register(GIE);

/* set adc */
   	ADC10CTL0 = SREF_0 | ADC10SHT_1 | ADC10SR | ADC10IE;
   	ADC10CTL1 = INCH_2 | SHS_0 | ADC10DIV_0 | ADC10SSEL_1 | CONSEQ_0;
   	ADC10AE0 |= REG8_BIT_2;
    
	while(1)
	{
	/* 1 sec delay */
		TA0CTL |= TACLR;          /* reset timer */
		TA0CCTL0 = CCIE;          /* interupt enabled */
		TA0CCR0 = 12000U - 1U;    /* 1sec with 12Khz clock */
		TA0CTL = TASSEL0 | MC_1;  /* start timer */
		__bis_SR_register(LPM3_bits);
		_NOP();

	/* take adc read */
		ADC10CTL0 |= ADC10ON;                        //turn on ADC
		_NOP();                                      //settling time 30us for reference buffer

		ADC10CTL0 &= ~ENC;

		cnt = 1000U;
		while( (ADC10CTL1 & ADC10BUSY) && (--cnt));               // Wait if ADC10 core is active
		ADC10CTL0 |= ENC + ADC10SC;                  // Sampling and conversion start

		__bis_SR_register(LPM3);
		_NOP();

		ADC10CTL0 &= ~(ENC);                         //turn off adc module
		ADC10CTL0 &= ~(ADC10ON);

		value = ADC10MEM;
        
        do_some_calculations(value);
        
    }
}

void clock init(void)
{
    /*
     * Basic Clock System Control 2
     *
     * SELM_3 -- LFXTCLK
     * DIVM_0 -- Divide by 1
     * SELS -- XT2CLK when XT2 oscillator present. LFXT1CLK or VLOCLK when XT2 oscillator not present
     * DIVS_0 -- Divide by 1
     * ~DCOR -- DCO uses internal resistor
     *
     * Note: ~DCOR indicates that DCOR has value zero
     */
    BCSCTL2 = SELM_3 | DIVM_0 | SELS | DIVS_0;

    if (CALBC1_1MHZ != 0xFF) {
        /* Follow recommended flow. First, clear all DCOx and MODx bits. Then
         * apply new RSELx values. Finally, apply new DCOx and MODx bit values.
         */
        DCOCTL = 0x00;
        BCSCTL1 = CALBC1_1MHZ;      /* Set DCO to 1MHz */
        DCOCTL = CALDCO_1MHZ;
    }

    /*
     * Basic Clock System Control 1
     *
     * XT2OFF -- Disable XT2CLK
     * ~XTS -- Low Frequency
     * DIVA_0 -- Divide by 1
     *
     * Note: ~XTS indicates that XTS has value zero
     */
    BCSCTL1 |= XT2OFF | DIVA_0;

    /*
     * Basic Clock System Control 3
     *
     * XT2S_0 -- 0.4 - 1 MHz
     * LFXT1S_2 -- If XTS = 0, XT1 = VLOCLK ; If XTS = 1, XT1 = 3 - 16-MHz crystal or resonator
     * XCAP_1 -- ~6 pF
     */
    BCSCTL3 = XT2S_0 | LFXT1S_2 | XCAP_1;


    do
    {
        // Clear OSC fault flag
        IFG1 &= ~OFIFG;

        // 50us delay
        __delay_cycles(1);
    } while (IFG1 & OFIFG);

/* disable smclk & disable dc generator */
  	__bis_SR_register(SCG1 + SCG0);
} 

  • From a previous post is is assumed that you are referring to a MSP430G2230 device. Higher core frequencies require more power to operate, therefore using a 1 MHz MCLK would be more efficient than 12 MHz. But this does not matter for much since the majority of the time you are in LPM3 where SMCLK and MCLK are disabled.

    The TACLK pin is not available on the G2230 device so TASSEL1 (ACLK) should be used instead, assuming that ACLK is sourced by the 12 kHz VLO.

    Compiler optimization has no correlation with power consumption.

    Regards,
    Ryan

  • Sry its 12khz internal ACLk which is made mclk, not 12Mhz. & yes MCU is MSP430G2330
  • ACLK and MCLK cannot source one another, instead they are sourced by other clocks. What you mean to say is that LFXT1CLK, which is provided by the VLOCLK, sources MCLK. MCLK is still disabled in LPM3 whereas ACLK is active. VLOCLK is optimal for the lowest power but is not as accurate as an external LFXT, therefore interrupts may vary by a few ms each second.

    Regards,
    Ryan

**Attention** This is a public forum