[资料] 利用MSP430实现的超低功耗触摸屏
971 查看
6 回复
 楼主 | 发布于 2018-09-27 | 只看楼主
分享到:
/*
               
                       低功耗电容感应式触摸演示程序


   程序说明:目前许多新型家用电器如电磁炉、微波炉、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 )
回复 举报

楼主 | 回复于 2018-09-27 沙发

(0 )
评论 (0) 举报

楼主 | 回复于 2018-09-27 2#

(0 )
评论 (0) 举报

回复于 2018-09-28 3#

感谢分享
(0 )
评论 (0) 举报

回复于 2018-09-30 4#

谢谢分享                
(0 )
评论 (0) 举报

回复于 2018-09-30 5#

谢谢分享                
(0 )
评论 (0) 举报

回复于 2018-10-19 6#

感谢分享,有需要机器人方案的可联系我,相互学习,共同进步
(0 )
评论 (0) 举报
  • 发表回复
    0/3000





    举报

    请选择举报类别

    • 广告垃圾
    • 违规内容
    • 恶意灌水
    • 重复发帖

    全部板块

    返回顶部