分享到:
/* 低功耗电容感应式触摸演示程序 程序说明:目前许多新型家用电器如电磁炉、微波炉、iPod等广泛使用感应式 按键。可以隔着玻璃、塑料等绝缘体通过触摸方式操作设备。因为 这种方式无触点、无机械部件、无接触,具有几乎无限长的寿命。 在《感应触摸板原理》程序中已经详细介绍了感应触摸板的工作 原理,但由于人体引入电磁干扰,非常容易误动作,可靠性很差。 并且CPU需工作在4MHz主频,耗电达到1.2mA。 本例中利用降低检测频率(每秒检测32次)来降低功耗至9.5uA。并 且用FIFO结构数组纪录相邻4次RC充电时间,判定按键条件由原来的 简单门限方法变成:必须连续4次都大于门限,才认为键按下;必须 连续4次都小于门限,才认为键松开。 采用上述判断方法后,几乎没有误动作,但按键略有延迟(1/8秒) 本程序已经能实用化,具体应用可参考《触摸控制的电子表》程序。 (C)西安电子科技大学 测控技术与仪器教研中心 编写:谢 楷 2008/02/01 */ // // // MSP430FE425 // +-------------------+ // | XIN|- // LED(红)<--|P1.3 | 32kHz // | XOUT|- // LED(绿)<--|P1.1 | | // | P2.3|------+------| 金属片1 (PAD1) // | | | | // | | R(4.7M) // | | | | // | P2.1|------+------| 金属片2 (PAD2) // | | | // #include <MSP430X42X.h> #define PAD1_OUT_H P2DIR|=BIT3; P2OUT|= BIT3 /*将PAD1置为高电平的宏定义*/ #define PAD1_OUT_L P2DIR|=BIT3; P2OUT&=~BIT3 /*将PAD1置为低电平的宏定义*/ #define PAD2_OUT_H P2DIR|=BIT1; P2OUT|= BIT1 /*将PAD2置为高电平的宏定义*/ #define PAD2_OUT_L P2DIR|=BIT1; P2OUT&=~BIT1 /*将PAD2置为低电平的宏定义*/ #define PAD1_DIR_IN P2DIR&=~BIT3 /*将PAD1设为输入状态的宏定义*/ #define PAD2_DIR_IN P2DIR&=~BIT1 /*将PAD2设为输入状态的宏定义*/ #define PAD1_IN (P2IN&BIT3) /*读回PAD1电平的宏定义*/ #define PAD2_IN (P2IN&BIT1) /*读回PAD2电平的宏定义*/ #define LED_RED_ON P1OUT|=BIT3 /*红灯亮的宏定义*/ #define LED_RED_OFF P1OUT&=~BIT3 /*红灯灭的宏定义*/ #define LED_GREEN_ON P1OUT|=BIT1 /*绿灯亮的宏定义*/ #define LED_GREEN_OFF P1OUT&=~BIT1 /*绿灯亮的宏定义*/ #define PAD1_THRESHOLD 28 /*PAD1 时间门限值*/ #define PAD2_THRESHOLD 27 /*PAD2 时间门限值*/ /*因为工艺误差,不同板子固有分布电容可能不同,门限值可能略有差异, 因此时间门限需要根据实际略微调整*/ unsigned char PAD1_BUFF[4]; //记录PAD1相邻4次充电时间的数组 unsigned char PAD2_BUFF[4]; //记录PAD2相邻4次充电时间的数组 unsigned char PAD1_REG=0; //记录PAD1状态 unsigned char PAD2_REG=0; //记录PAD2状态 /**************************************************************************** * 名 称:TouchPad_GetPad1() * 功 能:读回PAD1触摸板的状态 * 入口参数:无 * 出口参数:返回1表示有手指按在PAD1上,返回0表示PAD1未被触摸 * 说 明: 可靠性较高 ****************************************************************************/ char TouchPad_GetPad1(void) { return(PAD1_REG); } /********************************************************************** * 名 称:TouchPad_ScanPad1() * 功 能:定时扫描触控键PAD1的状态 * 入口参数:无 * 出口参数:无,结果保存在全局变量PAD1_REG内 * 说 明: 在1/32秒~1/256秒定时中断内调用该函数 **********************************************************************/ void TouchPad_ScanPad1(void) { int i,CNT; PAD2_OUT_H; //PAD2置高(对充电电阻提供VCC) PAD1_OUT_L; //PAD1置低 _NOP(); _NOP(); //略等待,将电荷泄放完 CNT=0; //------------------------------------------------------------------------ PAD1_DIR_IN; //PAD1置为输入状态 while(PAD1_IN==0){CNT++;} //在PAD1为低的过程中计数值增加 //------------------------------------------------------------------------ // 上面两句程序执行过程不允许被中断!如果可能会中断,请注意关中断 //------------------------------------------------------------------------ PAD1_BUFF[0]=PAD1_BUFF[1]; PAD1_BUFF[1]=PAD1_BUFF[2]; //FIFO,前3次值 PAD1_BUFF[2]=PAD1_BUFF[3]; PAD1_BUFF[3]=CNT; //记录低电平时间 for(i=0;i<4;i++) if(PAD1_BUFF[i]<PAD1_THRESHOLD) break; //任意一次小于门限则退出 if(i==4) PAD1_REG=1; //4次全部大于门限,才认为按下 for(i=0;i<4;i++) if(PAD1_BUFF[i]>=PAD1_THRESHOLD) break;//任意一次大于门限则退出 if(i==4) PAD1_REG=0; //4次全部小于门限,才认为松开 } /**************************************************************************** * 名 称:TouchPad_GetPad2() * 功 能:读回PAD2触摸板的状态 * 入口参数:无 * 出口参数:返回1表示有手指按在PAD2上,返回0表示PAD2未被触摸 * 说 明: 可靠性较高 ****************************************************************************/ char TouchPad_GetPad2(void) { return(PAD2_REG); } /********************************************************************** * 名 称:TouchPad_ScanPad2() * 功 能:定时扫描触控键PAD1的状态 * 入口参数:无 * 出口参数:无,结果保存在全局变量PAD2_REG内 * 说 明: 在1/32秒~1/256秒定时中断内调用该函数 **********************************************************************/ void TouchPad_ScanPad2(void) { int i,CNT; PAD1_OUT_H; //PAD1置高(对充电电阻提供VCC) PAD2_OUT_L; //PAD2置低 _NOP(); _NOP(); //略等待,将电荷泄放完 CNT=0; //------------------------------------------------------------------------ PAD2_DIR_IN; //PAD2置为输入状态 while(PAD2_IN==0){CNT++;} //在PAD2为低的过程中计数值增加 //------------------------------------------------------------------------ // 上面两句程序执行过程不允许被中断!如果可能会中断,请注意关中断 //------------------------------------------------------------------------ PAD2_BUFF[0]=PAD2_BUFF[1]; PAD2_BUFF[1]=PAD2_BUFF[2]; //FIFO,前3次值 PAD2_BUFF[2]=PAD2_BUFF[3]; PAD2_BUFF[3]=CNT; //记录低电平时间 for(i=0;i<4;i++) if(PAD2_BUFF[i]<PAD2_THRESHOLD) break; //任意一次小于门限则退出 if(i==4) PAD2_REG=1; //4次全部大于门限,才认为按下 for(i=0;i<4;i++) if(PAD2_BUFF[i]>=PAD2_THRESHOLD) break; //任意一次大于门限则退出 if(i==4) PAD2_REG=0; //4次全部小于门限,才认为松开 } /**************************************************************************** * 名 称:BT_ISR() 中断 * 功 能:每1/32秒唤醒CPU一次 * 入口参数:无 * 出口参数:无 ****************************************************************************/ #pragma vector = BASICTIMER_VECTOR __interrupt void BT_ISR(void) //1/32秒一次中断(由BasicTimer所产生) { int i; _BIC_SR(SCG0); // 从低功耗模式3唤醒需要手动清除SCG0,CPU时钟才准确 for(i=0;i<50;i++); // 略延迟,等待时钟稳定 TouchPad_ScanPad1(); TouchPad_ScanPad2(); __low_power_mode_off_on_exit(); //退出低功耗模式 } /**************************************************************************** * 名 称:主程序 * 功 能:将触摸板状态对应成不同颜色LED显示 * 入口参数:无 * 出口参数:无 ****************************************************************************/ void main( void ) { int volatile i; WDTCTL=WDTPW+WDTHOLD; //停止看门狗 FLL_CTL0|=XCAP18PF; //配置晶振负载电容 SCFQCTL=SCFQ_4M ; //MCLK = 128 * ACLK = 4MHz SCFI0=FN_4 ; // DCO centered at 4 MHz BTCTL = BTDIV+BT_fCLK2_DIV4; // 1/32s BT Int IE2 |= BTIE; // Enable Basic Timer interrupt P1DIR |=BIT4+BIT3+BIT1; // LED输出 P1DIR |=BIT0+BIT2; P2DIR |=BIT0+BIT2; //悬空不用的管脚置为输出 P1OUT=0; //避免感应不确定电平造成内部MOS导通,可省电 P2OUT=0; _EINT(); while(1) { LPM3; if(TouchPad_GetPad1()) LED_RED_ON; else LED_RED_OFF; if(TouchPad_GetPad2()) LED_GREEN_ON; else LED_GREEN_OFF; } }
(0 )
(0 )
回复
举报
- 0000000000000000
-
1888 发帖7917 回复34980 积分
- 私信他 +关注
发表回复
块
导
航
举报
请选择举报类别
- 广告垃圾
- 违规内容
- 恶意灌水
- 重复发帖