// Launchpad Touch Cap Sensing // Touch Key code #include // 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 Num_Sen 5 // Defines number of sensors // Definitions for use with the WDT settings #define DIV_ACLK_32768 (WDT_ADLY_1000) /* ACLK/32768 */ #define DIV_ACLK_8192 (WDT_ADLY_250) /* ACLK/8192 */ #define DIV_ACLK_512 (WDT_ADLY_16) /* ACLK/512 */ #define DIV_ACLK_64 (WDT_ADLY_1_9) /* ACLK/64 */ #define DIV_SMCLK_32768 (WDT_MDLY_32) /* SMCLK/32768 */ #define DIV_SMCLK_8192 (WDT_MDLY_8) /* SMCLK/8192 */ #define DIV_SMCLK_512 (WDT_MDLY_0_5) /* SMCLK/512 */ #define DIV_SMCLK_64 (WDT_MDLY_0_064) /* SMCLK/64 */ // Define Hardware Inputs/Outputs #define CA_Out (0x80) // Comparator output on P1.7 #define CA_Ref (0x02) // Comparator reference on P1.1 #define TA_Clk (0x01) // Timer_A clock input on P1.0 #define S_1 (0x04) // Sensor 1 P1.2 #define S_2 (0x08) // Sensor 2 P1.3 #define S_3 (0x10) // Sensor 3 P1.4 #define S_4 (0x20) // Sensor 4 P1.5 #define S_5 (0x40) // Sensor 4 P1.6 #define CA_1 (P2CA4) // Mux settings: CA+ Vref at CA1 #define CA_2 (P2CA2) // Mux settings: Sensor 1 at CA2 #define CA_3 (P2CA1+P2CA2) // Mux settings: Sensor 2 at CA2 #define CA_4 (P2CA3) // Mux settings: Sensor 3 at CA2 #define CA_5 (P2CA1+P2CA3) // Mux settings: Sensor 4 at CA2 #define CA_6 (P2CA2+P2CA3) // Mux settings: Sensor 4 at CA2 #define LED1 (0x40) // P2.6 #define LED2 (0x80) // P2.7 // Global variables for sensing unsigned int base_cnt[Num_Sen]; unsigned int meas_cnt[Num_Sen]; int delta_cnt[Num_Sen]; unsigned char key_press[Num_Sen]; const unsigned int KEY_lvl_S[5]={4000,40,40,90,100}; const unsigned int KEY_lvl_W[5]={4000,40,40,90,100}; char key_pressed, key_loc; int cycles; unsigned int LEDCount = 4000; unsigned int LEDTimer = 10; unsigned int swjudge = 0; // System Routines void measure_count(void); // Measures each capacitive sensor void pulse_LED(void); // LED gradient routine (for demo only) // Main Function void main(void) { volatile unsigned int i,j; WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1, 8, 12 or 16MHz DCOCTL = CALDCO_1MHZ; BCSCTL1 |= DIVA_0; // ACLK/(0:1,1:2,2:4,3:8) BCSCTL3 |= LFXT1S_2; // LFXT1 = VLO IE1 |= WDTIE; // enable WDT interrupt P1OUT = 0x00; // P1.x = 0 P1DIR = 0xFE; // P1.0 = TACLK input P1SEL |= 0x81; // P1.0 = TACLK input, P1.7 = CAOUT P2OUT = 0x00; // P2SEL = 0x00; // No XTAL P2DIR |= LED1+LED2; P2OUT |= LED2; P2SEL |= LED1; CAPD = CA_Ref; // disable input buffer for CA+ ref input CACTL2 = CA_1; // CA1 = CA+ Vref _EINT(); // Enable interrupts measure_count(); // Establish an initial baseline capacitance for (i = 0; i { if(meas_cnt>1000) swjudge++; } for (i = 0; i base_cnt = meas_cnt; for(i=15; i>0; i--) // Repeat and average base measurement { measure_count(); for (j = 0; j base_cnt[j] = (meas_cnt[j]+base_cnt[j])/2; } // Main loop starts here while (1) { key_pressed = 0; // Assume no keys are pressed measure_count(); // Measure all sensors for (i = 0; i { delta_cnt = base_cnt - meas_cnt; // Calculate delta: c_change // Handle baseline measurment for a base C decrease if (delta_cnt < 0) // If negative: result increased { // beyond baseline, i.e. cap decreased delta_cnt = 0; // Zero out delta for position determination } if(swjudge == 1) { if (delta_cnt > KEY_lvl_W) // Determine if each key is pressed per a preset threshold { key_press = 1; // Specific key pressed key_pressed = 1; // Any key pressed P2OUT ^= LED2; while(LEDTimer--) { LEDCount -= 5; if(LEDCount<10)LEDCount=4000; pulse_LED(); } LEDTimer=10; } else key_press = 0; } else if(swjudge == 2) { if (delta_cnt > KEY_lvl_S) // Determine if each key is pressed per a preset threshold { key_press = 1; // Specific key pressed key_pressed = 1; // Any key pressed P2OUT ^= LED2; while(LEDTimer--) { LEDCount -= 5; if(LEDCount<10)LEDCount=4000; pulse_LED(); } LEDTimer=10; } else key_press = 0; } else key_press = 0; } WDTCTL = WDT_delay_setting; // WDT, ACLK, interval timer LPM3; // accomodate for genuine changes in sensor C } } // End Main // Measure count result (capacitance) of each sensor // Routine setup for four sensors, not dependent on Num_Sen value! void measure_count(void) { char i; TACTL = TASSEL_0+MC_2; // TACLK, cont mode TACCTL1 = CM_3+CCIS_2+CAP; // Pos&Neg,GND,Cap CACTL1 |= CAON; // Turn on comparator for (i = 0; i { switch (i) { case 1: // Sensor 1 CAPD = CA_Ref+S_1; // Diable I/Os for CA1 ref, 1st sensor CACTL2 = CA_1+CA_2; // CA1 ref, CAx sensor break; case 2: // Sensor 2 CAPD = CA_Ref+S_2; // Diable I/Os for CA1 ref, 2nd sensor CACTL2 = CA_1+CA_3; // CA1 ref, CAx sensor break; case 3: // Sensor 3 CAPD = CA_Ref+S_3; // Diable I/Os for CA1 ref, 3rd sensor CACTL2 = CA_1+CA_4; // CA1 ref, CAx sensor break; case 4: // Sensor 4 CAPD = CA_Ref+S_4; // Diable I/Os for CA1 ref, 4th sensor CACTL2 = CA_1+CA_5; // CA1 ref, CAx sensor break; case 0: // Sensor 5 CAPD = CA_Ref+S_5; // Diable I/Os for CA1 ref, 4th sensor CACTL2 = CA_1+CA_6; // CA1 ref, CAx sensor break; } WDTCTL = WDT_meas_setting; // Set duration of sensor measurment TACTL |= TACLR; // Clear Timer_A TAR LPM0; // Wait for WDT interrupt meas_cnt = TACCR1; // Save result WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer } CACTL1 &= ~CAON; // Turn off comparator CAPD = CA_Ref; // Re-init Mux: all sensors = GND } void pulse_LED(void) { TACTL = TACLR; CCR0 = 5000; CCTL0 = OUTMOD_4;//+CCIE; CCR1 = LEDCount; CCTL1 = OUTMOD_4+CCIE; TACTL = TASSEL_2 + MC_3; _BIS_SR(LPM0_bits + GIE); // Enter LPM0 w/ interrupt } // Watchdog Timer interrupt service routine #pragma vector=WDT_VECTOR __interrupt void watchdog_timer(void) { TACCTL1 ^= CCIS0; // Create SW capture of CCR1 LPM3_EXIT; // Exit LPM3 on reti } // Timer A1 interrupt service routine #pragma vector=TIMERA1_VECTOR __interrupt void Timer_A1 (void) { TACCTL1 &= ~CCIE; // interrupt disbled LPM0_EXIT; } 轉自:電子工程世界( EEWORLD )http //www eeworld com cn/ |