上面第四步中example.c源代码如下:/* 单片机型号 m430g2452 */
#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 10 //不能太大 Defines threshold for a key press
/*Set to ~ half the max delta expected*/
/* 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 LED_1 (0x01) // P1.0 LED output
#define LED_2 (0x40) // P1.6 LED output
// Global variables for sensing
unsigned int base_cnt, meas_cnt; //base_cnt为没有按键时计算来的基准计数,通常不变 meas_cnt为实时测来的计数,没按键时和base_cnt接近,按键时要比和base_cnt大
int delta_cnt; //base_cnt和meas_cnt之差,作为是否按键的依据
char key_pressed; //是否按键的标志
/* System Routines*/
void measure_count(void); // Measures each capacitive sensor
void pulse_LED(void); // LED gradient routine
/* Main Function*/
void main(void)
{
unsigned int i,j;
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1MHz
DCOCTL = CALDCO_1MHZ;
BCSCTL3 |= LFXT1S_2; // ACLK通常由LFXT1作为时钟源,所以ACLK即VLO LFXT1 = VLO
IE1 |= WDTIE; // enable WDT interrupt
P1DIR = LED_1 + LED_2; // P1.0 & P1.6 = LEDs
P1OUT = 0x00;
__bis_SR_register(GIE); // Enable interrupts 使能全局中断
measure_count(); // Establish baseline capacitance
base_cnt = meas_cnt;
for(i=15; i>0; i--) // 计算base_cnt的平均值
{
measure_count();
base_cnt = (meas_cnt+base_cnt)/2;
}
/* Main loop starts here*/
while (1)
{
j = KEY_LVL;
key_pressed = 0; // Assume no keys are pressed
measure_count(); // Measure all sensors
delta_cnt = base_cnt - meas_cnt; // Calculate delta: c_change
_nop();//方便调试时设置断点,观察delta_cnt等的数值
/* Handle baseline measurment for a base C decrease*/
if (delta_cnt < 0) // If negative: result increased
{ // beyond baseline, i.e. cap dec
base_cnt = (base_cnt+meas_cnt) >> 1; // Re-average quickly
delta_cnt = 0; // Zero out for pos determination
}
if (delta_cnt > j) // Determine if each key is pressed
{ // per a preset threshold
j = delta_cnt;
key_pressed = 1; // key pressed
}
else
key_pressed = 0;
pulse_LED(); // 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)
{
TA0CTL = TASSEL_3+MC_2; // TASSEL_3目的是把PinOscillator作为时钟源
TA0CCTL1 = CM_3+CCIS_2+CAP; // CM_3上升下降沿都计数,CAP捕捉模式 , CCIS_2此时不进行捕捉
/*决定哪个io口作为电容按键的输入接口*/
P2DIR &= ~ BIT5; // P2.5 中键 P2.1左键 P2.2下键 P2.3右键 P2.4上键 P2.0外边沿
P2SEL &= ~ BIT5;
P2SEL2 |= BIT5;
/*Setup Gate Timer*/
WDTCTL = WDT_meas_setting; // 启动看门狗 工作在计数器模式下 WDT, ACLK, interval timer
TA0CTL |= TACLR; // 清零 TAR
__bis_SR_register(LPM0_bits+GIE); // 关闭cpu但计数器仍然工作,这样做的目的是确保下面的代码在看门狗中断发生后才执行
TA0CCTL1 ^= CCIS0; // 捕捉一次计数器的计数值,即将此时的TAR复制到TACCR1
meas_cnt = TACCR1; // 保存TACCR1,即在看门狗计数器启动到中断发生这段时间内发生的PinOscillator脉冲个数
WDTCTL = WDTPW + WDTHOLD; // 关闭看门狗
}
void pulse_LED(void)
{
if(key_pressed) //按下时 led0、1亮
{
P1OUT |= LED_1 + LED_2;
}else{
P1OUT = 0;
}
}
/* Watchdog Timer interrupt service routine*/
#pragma vector=WDT_VECTOR
__interrupt void watchdog_timer(void)
{
__bic_SR_register_on_exit(LPM3_bits); // 重新启动cpu
}
|