Hi guys
I am using msp430g2452, my timer A fire every 100ms and start ADC10 reading every 6 seconds. The ADC result is handle in ADC10 interrupt. What I found is I CANNOT turn off the ADC10 (mainly the internal Vref) in ADC10 interrupt to save power. But I CAN turn off ADC10 with the same code in my Timer A interrupt.
The following codes use more current, ~180uA, gussing ADC10 is not turn off.
but if I move move the code that turn off ADC10 to the timer A interrupt, it works, current draws reduce to ~10uA.
If I turn off the ADC10 in my timer interrupt, it can have a delay between 0-100ms, and I want to minimize the current draw of my application, so how can I turn off the ADC10 properly ASAP after it done reading?
Thanks guys
James
I am using msp430g2452, my timer A fire every 100ms and start ADC10 reading every 6 seconds. The ADC result is handle in ADC10 interrupt. What I found is I CANNOT turn off the ADC10 (mainly the internal Vref) in ADC10 interrupt to save power. But I CAN turn off ADC10 with the same code in my Timer A interrupt.
The following codes use more current, ~180uA, gussing ADC10 is not turn off.
Code:
// Timer A0 interrupt service routine
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A (void)
{
// reset ADC10 to save power
// ADC10CTL0 = 0;
// ADC10CTL1 = 0;
// other stuff, removed for easy reading
// check voltage
{
static unsigned int counter = 0;
counter++;
if (counter == 60) // every count is 100ms, 60 counts is about 6 seconds
{
counter = 0; // reset counter
ADC10CTL0 |= SREF_1; // VR+ = VREF+, VR- = VSS
ADC10CTL0 |= ADC10SHT_2; // sample and hold time = 16 x ADC10CLK
ADC10CTL0 |= REFON; // reference on
ADC10CTL0 |= ADC10ON; // ADC10 on
ADC10CTL0 |= ADC10IE; // interrupt enable
__delay_cycles(30); // wait ~30us for Vref to stablise
ADC10CTL1 |= INCH_11; // input = (Vcc - Vss)/2
ADC10CTL0 |= ENC; // ADC10 enable
ADC10CTL0 |= ADC10SC; // start conversion
}
}
}
// ADC10 interrupt service routine
#pragma vector = ADC10_VECTOR
__interrupt void ADC10_ISR(void)
{
if (ADC10MEM < 852) // 852 ~= 2.5V
TMP_ENGAGED(); // engage temper alarm
else if (ADC10MEM > 886) // 886 ~= 2.6V
TMP_DIS_ENGAGED(); // disengage temper alarm
// the following two lines reset ADC10, turning it off
ADC10CTL0 = 0;
ADC10CTL1 = 0;
}
Code:
// Timer A0 interrupt service routine
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A (void)
{
// reset ADC10 to save power
ADC10CTL0 = 0;
ADC10CTL1 = 0;
// other stuff, removed for easy reading
// check voltage
{
static unsigned int counter = 0;
counter++;
if (counter == 60) // every count is 100ms, 600 counts is about 1 minutes
{
counter = 0; // reset counter
ADC10CTL0 |= SREF_1; // VR+ = VREF+, VR- = VSS
ADC10CTL0 |= ADC10SHT_2; // sample and hold time = 16 x ADC10CLK
ADC10CTL0 |= REFON; // reference on
ADC10CTL0 |= ADC10ON; // ADC10 on
ADC10CTL0 |= ADC10IE; // interrupt enable
__delay_cycles(30); // wait ~30us for Vref to stablise
ADC10CTL1 |= INCH_11; // input = (Vcc - Vss)/2
ADC10CTL0 |= ENC; // ADC10 enable
ADC10CTL0 |= ADC10SC; // start conversion
}
}
}
// ADC10 interrupt service routine
#pragma vector = ADC10_VECTOR
__interrupt void ADC10_ISR(void)
{
if (ADC10MEM < 852) // 852 ~= 2.5V
TMP_ENGAGED(); // engage temper alarm
else if (ADC10MEM > 886) // 886 ~= 2.6V
TMP_DIS_ENGAGED(); // disengage temper alarm
}
Thanks guys
James