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);
}