Hi folks,
i´ve been working on capacitive RC touch sensing and looking for the lowest power for a few days with no good results. I´m using MSP430G2553 on the Launchpad and to sum up this is what i´m trying to do:
1 º Use VLO as a source for Timer_A0 to generate a 4Hz interrupt.
2º Use this 4Hz interrupt to start a scanning of the electrode using the RC method. In this case, the DCO at 16MHz is the source for the Timer_A1, so you can measure the difference in the number of cycles for the Pin-negative-edge-triggered interrupt.
3º When the pin-negative-edge-triggered interrupt is detected, the difference in cycles is measured and compared to a threshold so you can decide if there is a finger or no.
This is the code:
*********************************************************************************************************************
*********************************************************************************************************************
*********************************************************************************************************************
#include <msp430g2553.h>
unsigned int timer_count;
void main(){
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
BCSCTL1 = CALBC1_16MHZ; // Set DCO to 1, 8, 12 or 16MHz
DCOCTL = CALDCO_16MHZ;
BCSCTL3 |= LFXT1S_2;
// CONFIGURO EL TIMER 0 Y EL CCR0
TA0CCTL0 &= ~CCIE; // CCR0 interrupt disable
TA0CTL = TASSEL_2 + MC_0; // SMCLK and Continous up
// CONFIGURO EL TIMER 0 Y EL CCR0
TA1CCTL0 |= CCIE; // CCR0 interrupt enable para 32768Hz es un segundo
TA1CCR0 = 5000; // The number of timer counts in the period is TACCR0+1.
TA1CTL = TASSEL_1 + MC_1; // ACLK and up to CCR0
P2SEL &= ~BIT6 + ~BIT7; // GPIO function
P1DIR = 0xFF; // out
P1OUT = 0; // 0
P2DIR = 0xFF; // out
P2OUT = 0; // 0
ADC10CTL0 &= ~ENC; // Disable ADC conversion
ADC10CTL0 &= ~(REFON + ADC10ON); // Ref and ADC10 off
_BIS_SR(GIE); // Enter LPM0 w/ interrupt
while(1){
/* Take the active key high to charge the pad */
TA0R = 0;
TA0CTL = TASSEL_2 + MC_2; // SMCLK and Continous up
P1OUT |= BIT4;
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
// Enable interrupts (edge set to low going trigger)
// set the active key to input (was output high), and start the
// timed discharge of the pad.
P1IES |= BIT4; //-ve edge trigger
P1IE |= BIT4;
P1DIR &= ~BIT4;
/* Take a snaphot of the timer... */
timer_count = TA0R;
LPM0;
P1IE &= ~BIT4; // disable active key interrupt
P1OUT &= ~BIT4; // switch active key to low to discharge the key
P1DIR |= BIT4; // switch active key to output low to save power
LPM3;
}
}
#pragma vector=PORT1_VECTOR
__interrupt void port_1_interrupt(void)
{
TA0CTL = TASSEL_2 + MC_0; // SMCLK and Continous up
timer_count = TA0R - timer_count;
if((timer_count > 2500) && (P1IFG == BIT4)){
P1OUT ^= BIT0;
}
P1IFG = 0; // clear flag
LPM3_EXIT; // Exit LPM3 on reti
}
// Timer_A2 Interrupt Vector (TA0IV) handler
#pragma vector=TIMER1_A0_VECTOR
__interrupt void Timer1_A0(void)
{
_BIC_SR_IRQ(LPM3_bits); // Clear LPM3 bits from 0(SR)
}
*********************************************************************************************************************
*********************************************************************************************************************
*********************************************************************************************************************
I achieved 67uA, but i think i´m doing something wrong, because as i see in some application notes, the current consumption in LPM3 is in the order of the hundreds of nA. This code stays in LPM3 most of the time so i think the current ought be much lower than 67uA.
Any advice?? Anything would be very appreciated! Thanks in advanced!
Alvaro G