长短键识别

功能实现

  MSP-EXP430G2 开发板上 P1.3 接了一个按键,P1.0 和 P1.6 接了 LED(用跳线帽连接),要求短按 P1.3 控制 LED1 的亮灭,长按P1.3 控制 LED2 的亮灭。

状态机

Created with Raphaël 2.1.0 长短键识别状态机 S0待机 S0待机 S1短按 S1短按 S2长按 S2长按 1.按键按下事件/ 2.按键松开事件/短键事件处理 3.计数门限事件/长键事件处理 4.按键松开事件/

代码

#include "MSP430G2553.h" 

//-----对状态机进行宏定义----- 
#define IDLE                 0 
#define SHORT                1 
#define LONG                 2 
#define COUNTER_THRESHOLD             50        /*长键判别门限*/ 
//-----全局变量----- 
unsigned char WDT_Counter=0;                   /*用于对按键按下时间进行计数*/ 
//-----在main函数前提前声明函数----- 
void GPIO_init(); 
void WDT_init(); 
void Key_SM(); 
unsigned char LongClick_Dect(); 
void P13_OnShortRelease(); 
void P13_OnLongClick(); 

void main(void) { 
  WDTCTL = WDTPW + WDTHOLD;                    //关狗 
  GPIO_init(); 
  WDT_init(); 
  _EINT();                                    //开总中断 
  LPM3;                                       //LPM3休眠 
}

/******************************************************************************************************  
  * 名    称:GPIO_init() 
  * 功    能:设定按键和LED控制IO的方向,启用按键IO的上拉电阻 
  * 入口参数:无 
  * 出口参数:无 
  * 说    明:无 
  * 范    例:无 
******************************************************************************************************/ 
void GPIO_init() 
{ 
  //-----设定P1.0和P1.6的输出初始值----- 
  P1DIR |= BIT0+BIT6;               //设定P1.0和P1.6为输出 
  P1OUT |= BIT0;                    //设定P1.0初值 
  P1OUT &= ~BIT6;                   //设定P1.6初值 
  //-----配合机械按键,启用内部上拉电阻----- 
  P1REN |= BIT3;                    //启用P1.3内部上下拉电阻 
  P1OUT |= BIT3;                    //将电阻设置为上拉 
} 

/******************************************************************************************************  
  * 名    称:WDT_init() 
  * 功    能:设定WDT定时中断为16ms,开启WDT定时中断使能 
  * 入口参数:无 
  * 出口参数:无 
  * 说    明:WDT定时中断的时钟源选择ACLK,可以用LPM3休眠。 
  * 范    例:无 
******************************************************************************************************/ 
void WDT_init() 
{ 
  //-----设定WDT为----- 
  WDTCTL=WDT_ADLY_16; 
  //-----WDT中断使能----- 
     IE1|=WDTIE; 
} 

/******************************************************************************************************  
  * 名    称:WDT_ISR() 
  * 功    能:响应WDT定时中断服务 
  * 入口参数:无 
  * 出口参数:无 
  * 说    明:不能直接判断事件,需启用状态机 
  * 范    例:无 
******************************************************************************************************/ 
#pragma vector=WDT_VECTOR 
__interrupt void WDT_ISR(void) 
{ 
  //-----启用按键状态机----- 
  Key_SM(); 
} 

/****************************************************************************************************** 
  * 名    称:Key_SM() 
  * 功    能:判断出长短键 
  * 入口参数:无 
  * 出口参数:无 
  * 说    明:本状态机为Mealy型状态机,在Switch(State)中需要判断事件 
  * 范    例:无 
******************************************************************************************************/ 
void Key_SM() 
{ 
  static unsigned char State=0;       //状态机的状态变量 
  static unsigned char Key_Now=0;     //记录按键的当前电平 
  unsigned char Key_Past=0;           //记录按键的前一次电平 
  unsigned char Key_Dect=0;           //按键状态值 
  Key_Past=Key_Now; 
  //-----查询IO的输入寄存器----- 
  if(P1IN&BIT3)   Key_Now=1; 
  else            Key_Now=0; 
  //-----电平前高后低,表明按下----- 
  if((Key_Past==1)&&(Key_Now==0)) 
    Key_Dect=1; 
  //-----电平前低后高,表明弹起----- 
  if((Key_Past==0)&&(Key_Now==1)) 
    Key_Dect=2 ; 
  switch(State)                             //该状态机靠扫描的按键值Key_Dect跳转状态 
  { 
  case  IDLE:     
    WDT_Counter=0;                          //空闲状态对计数清零 
    if(Key_Dect==1)    State=SHORT;         //路径1 
    break;    
  case SHORT:     
    if(Key_Dect==2)                         //路径2 
    { 
      State=IDLE; 
      P13_OnShortRelease();                 //短按事件处理函数 
      break;
    } 
    if(LongClick_Dect())                    //路径3 
    { 
      State=LONG; 
      P13_OnLongClick();                    //长按事件处理函数 
    } 
    break; 
  case LONG:    
    WDT_Counter=0;                          //长按状态对计数清零 
    if(Key_Dect==2)     State=IDLE;         //路径4 
    break;      
  default:         State=IDLE;               break; 
  } 
} 

/******************************************************************************************************  
   * 名    称:LongClick_Dect() 
   * 功    能:对WDT中断计时,计满清零并返回”长键“信息 
   * 入口参数:无 
   * 出口参数:1:长按键;0:非长按键 
   * 说    明:无 
   * 范    例:无 
******************************************************************************************************/ 
unsigned char LongClick_Dect() 
{ 
  WDT_Counter++; 
  if (WDT_Counter==COUNTER_THRESHOLD) 
  { 
    WDT_Counter=0; 
    return(1); 
  } 
  else return(0); 
} 

/******************************************************************************************************  
  * 名    称:P13_OnShortRelease() 
  * 功    能:P1.3的短按事件处理函数,即当P1.3键被”短按“后,下一步干什么 
  * 入口参数:无 
  * 出口参数:无 
  * 说    明:使用事件处理函数的形式,可以增强代码的移植性和可读性 
  * 范    例:无 
******************************************************************************************************/ 
void P13_OnShortRelease()          //P1.3的事件处理函数 
{ 
  //----翻转P1.3IO电平----- 
  P1OUT ^= BIT0; 
} 
/******************************************************************************************************  
  * 名    称:P13_OnLongClick() 
  * 功    能:P1.3的长按事件处理函数,即当P1.3键被”长按“后,下一步干什么 
  * 入口参数:无 
  * 出口参数:无 
  * 说    明:使用事件处理函数的形式,可以增强代码的移植性和可读性 
  * 范    例:无 
  ******************************************************************************************************/ 
void P13_OnLongClick()            //P1.3的事件处理函数 
{ 
  //----翻转P1.6IO电平----- 
  P1OUT ^= BIT6; 
} 
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值