//****************************************************************************** // MSP430G2xx2 Demo - Capacitive Touch, Pin Oscillator Method, button // // Description: Basic 1-button input using the built-in pin oscillation feature // on GPIO input structure PinOsc signal feed into TA0CLK WDT interval is used // to gate the measurements Difference in measurements indicate button touch // LEDs flash if input is touched // // ACLK = VLO = 12kHz, MCLK = SMCLK = 1MHz DCO // // MSP430G2xx2 // // /|\| XIN|// | | | // |RST XOUT|// | | // | P1.1|< Capacitive Touch Input // | | // LED < |P1.6 | // | | // LED < |P1.0 | // | | // | | // // Brandon Elliott/D Dang // Texas Instruments Inc // November 2010 // Built with IAR Embedded Workbench Version: 5.10 //****************************************************************************** #include "msp430g2452.h" /* Define User Configuration values */ /* */ /* Defines WDT SMCLK interval for sensor measurements*/ #define WDT_meas_setting (DIV_SMCLK_512) /* Defines WDT ACLK interval for delay between measurement cycles*/ #define WDT_delay_setting (DIV_ACLK_512) /* Sensor settings*/ #define KEY_LVL 220 /*Set to ~ half the max delta expected*/ // Defines threshold for a key press /* Definitions for use with the WDT settings*/ #define DIV_ACLK_32768 (WDT_ADLY_1000) // #define DIV_ACLK_8192 (WDT_ADLY_250) // #define DIV_ACLK_512 (WDT_ADLY_16) // #define DIV_ACLK_64 (WDT_ADLY_1_9) // #define DIV_SMCLK_32768 (WDT_MDLY_32) // #define DIV_SMCLK_8192 (WDT_MDLY_8) // #define DIV_SMCLK_512 (WDT_MDLY_0_5) // #define DIV_SMCLK_64 (WDT_MDLY_0_064) // #define LED_1 #define LED_2 (0x01) (0x40) // Global variables for sensing unsigned int base_cnt, meas_cnt; int delta_cnt; char key_pressed; int cycles; /* System Routines*/ ACLK/32768 ACLK/8192 ACLK/512 ACLK/64 SMCLK/32768 SMCLK/8192 SMCLK/512 SMCLK/64 // P1.0 LED output // P1.6 LED output void measure_count(void); void pulse_LED(void); /* Main Function*/ void main(void) { unsigned int i,j; WDTCTL = WDTPW + WDTHOLD; BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; BCSCTL3 |= LFXT1S_2; IE1 |= WDTIE; P2SEL = 0x00; P1DIR = LED_1 + LED_2; P1OUT = 0x00; bis_SR_register(GIE); // Measures each capacitive sensor // LED gradient routine // Stop watchdog timer // Set DCO to 1MHz // LFXT1 = VLO // enable WDT interrupt // No XTAL // P1.0 & P1.6 = LEDs // Enable interrupts measure_count(); base_cnt = meas_cnt; // Establish baseline capacitance for(i=15; i>0; i ) { measure_count(); base_cnt = (meas_cnt+base_cnt)/2; } // Repeat and avg base measurement /* Main loop starts here*/ while (1) { j = KEY_LVL; key_pressed = 0; measure_count(); delta_cnt = base_cnt - meas_cnt; // Assume no keys are pressed // Measure all sensors // Calculate delta: c_change /* Handle baseline measurment for a base if (delta_cnt < 0) // { // base_cnt = (base_cnt+meas_cnt) >> 1; delta_cnt = 0; // } if (delta_cnt > j) // { // j = delta_cnt; key_pressed = 1; // } else key_pressed = 1; C decrease*/ If negative: result increased beyond baseline, i.e cap dec // Re-average quickly Zero out for pos determination Determine if each key is pressed per a preset threshold key pressed /* Delay to next sample, sample more slowly if no keys are pressed*/ if (key_pressed) { BCSCTL1 = (BCSCTL1 & 0x0CF) + DIVA_0; // ACLK/(0:1,1:2,2:4,3:8) cycles = 20; } else { cycles ; if (cycles > 0) BCSCTL1 = (BCSCTL1 & 0x0CF) + DIVA_0; // ACLK/(0:1,1:2,2:4,3:8) else { BCSCTL1 = (BCSCTL1 & 0x0CF) + DIVA_3; // ACLK/(0:1,1:2,2:4,3:8) cycles = 0; } } WDTCTL = WDT_delay_setting; // WDT, ACLK, interval timer /* Handle baseline measurment for a base C increase*/ if (!key_pressed) // Only adjust baseline down { // if no keys are touched base_cnt = base_cnt - 1; // Adjust baseline down, should be } // slow to accomodate for genuine pulse_LED(); // changes in sensor C } bis_SR_register(LPM3_bits); } // End Main /* Measure count result (capacitance) of each sensor*/ /* Routine setup for four sensors, not dependent on NUM_SEN value!*/ void measure_count(void) { TA0CTL = TASSEL_3+MC_2; TA0CCTL1 = CM_3+CCIS_2+CAP; // TACLK, cont mode // Pos&Neg,GND,Cap /*Configure Ports for relaxation oscillator*/ /*The P2SEL2 register allows Timer_A to receive it's clock from a GPIO*/ /*See the Application Information section of the device datasheet for info*/ P1DIR &= ~ BIT1; // P1.1 is the input used here P1SEL &= ~ BIT1; P1SEL2 |= BIT1; /*Setup Gate Timer*/ WDTCTL = WDT_meas_setting; TA0CTL |= TACLR; bis_SR_register(LPM0_bits+GIE); TA0CCTL1 ^= CCIS0; meas_cnt = TACCR1; WDTCTL = WDTPW + WDTHOLD; P1SEL2 &= ~BIT1; // // // // // // WDT, ACLK, interval timer Clear Timer_A TAR Wait for WDT interrupt Create SW capture of CCR1 Save result Stop watchdog timer } void pulse_LED(void) { if(key_pressed) { P1OUT ^= LED_1 + LED_2; }else{ P1OUT = 0; } } /* Watchdog Timer interrupt service routine*/ #pragma vector=WDT_VECTOR interrupt void watchdog_timer(void) { TA0CCTL1 ^= CCIS0; // Create SW capture of CCR1 bic_SR_register_on_exit(LPM3_bits); // Exit LPM3 on reti }