分享到:
/*
低功耗电容感应式触摸演示程序
程序说明:目前许多新型家用电器如电磁炉、微波炉、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 积分
- 私信他 +关注
发表回复
版
块
导
航
块
导
航
举报
请选择举报类别
- 广告垃圾
- 违规内容
- 恶意灌水
- 重复发帖

发帖
回复
楼主