【CC2530授课笔记】③ 双击及长按按键的原理与实现(51内核单片机)

实验套件介绍

在这里插入图片描述
如图所示是我们的CC2530实验套件,从图上可以看出,板子中间有四个LED,分别是:LED3,LED4,LED1,LED2
板子上有两个按键SW1和SW2分别对应引脚 P1.2和P0.1

本节课任务

①、实现SW1按键双击功能,控制LED4,双击返回11
②、实现SW1按键长按功能,控制LED1,长按返回111

按键波形图

单击按键波形图

单击按键波形图

双击按键波形图

双击按键波形图

双击按键实现步骤

双击按键单击按键对比

双击按键实现代码

unsigned char KeyScan(void)
{  
      if(SW1 == 0)       //低电平有效
      {
            Delay_mS(50);     //按键消抖
            if(SW1 == 0)   //按键第一次被按下
            {
                 while(!SW1);  //等待第一次按键被抬起
        
                 Delay_mS(100);     //延时一段时间,检测是否有双击(双击时间间隔)
	         
	         char time = 10;
	         while(time--)
	         {
	                if(SW1 == 0) //如果按键再次被按下
                  	{
                        	while(!SW1); //等待第二次按键松开
                        	return (11); //返回11,代表按键被双击
                  	}
                  }
                  return(1); //按键没有被第二次按下,认为是单击按键,返回1
            }
      }
      return(0);
}

长按按键

长按按键的波形图:
长按按键波形图

长按按键的实现步骤:

长按按键实现步骤

①按键第一次被按下后,通过一个变量记录按键被按下的持续时间
②如果按键的持续时间小于我们给定的时间,则认为是单击操作,返回 1
③如果按键的持续时间大于我们给定的时间,则认为是长按操作,返回 111

长按按键实现代码:

unsigned char KeyScan(void)
{
	unsigned char time;
	if(SW1 == 0)       //低电平有效
	{
		Delay_mS(50);     //消除抖动
		if(SW1 == 0)
		{
			time = 0;
			while(!SW1)   //等待松开按键
			{
				Delay_mS(10);     //延时
				time ++;    //记录按键被按下的时长
			}  
			
			if(time > 150)  //按下的时长大于我们是定的时间 1500mS
			{
				return(111);  //认为是长按操作,返回 111
			}   
			else   //按下的时长小于我们是定的时间
			{
				return(1);   //认为是单击操作,返回 1
			}
		}
		return(0);
	}
}

单击双击 长按 共存

同学们根据上诉讲解,同时实现单击、双击、长按的效果,
具体要求是:

①单击SW1控制LED3的亮与灭
②双击SW1控制LED4的亮与灭
③长按SW1控制LED1的亮与灭

完整的代码

#include <ioCC2530.h>
//定义控制灯的端口
#define LED1 P1_0 //定义LED1为P1_0口控制
#define LED2 P1_5 //定义LED2为P1_5口控制
#define LED3 P1_3 //定义LED3为P1_3口控制
#define LED4 P1_4 //定义LED4为P1_4口控制

#define SW1 P1_2        //定义SW1为P1_2端口
#define SW2 P0_1        //定义SW2为P0_1端口

/****************************
//延时
*****************************/
char pause = 0;
void Delay_mS(unsigned int n)
{
 	unsigned int tt,i = 0;
        for(i = 0; i < n; i ++)
   		for(tt = 0; tt<1040; tt++);
   		
        while(pause);
}

void Delay_uS(unsigned int n)
{
  	unsigned int i = 0;
  	for(;i < n; i++);
}

/****************************
//初始化函数
*****************************/
void Initial(void)
{
        CLKCONCMD &= 0x80;//使用外部32MHz晶振
        P1DIR = 0xFB;//将P12设为输入,其他设为输出 (0xFB = 11111011)
 	LED1 = 0;//关闭LED1
        LED2 = 0;//关闭LED2
        LED3 = 0;//关闭LED3
        LED4 = 0;//关闭LED4
}

unsigned short time = 0;
unsigned char long_click_flag = 0;
/*****************************************
//读键值
//单击返回1
//双击返回11
//长按返回111
*****************************************/
unsigned char KeyScan(void)
{
  if(long_click_flag == 1) //长按还未抬起
  {
    if(SW1 == 1) //长按按键被抬起
    {
      long_click_flag = 0;
    }
    return 0;
  }
  if(SW1 == 0)       //有按键按下
  {
    Delay_mS(50);     //消除抖动
    if(SW1 == 0)
    {
        time = 0;
        while(!SW1) //直到松开按键
        {
          Delay_mS(1);
          time ++;
          if(time > 1500)  //按下时间大于1.5S,认为是长按
          {
            long_click_flag = 1;
            return (111);
          }
        }
        Delay_mS(100);     //延时一段时间,检测是否有双击(双击时间间隔)
        time = 10;
        while(time--)
        {
          if(SW1 == 0) //按键再次被按下
          {
            while(!SW1); //直到松开按键
            return (11);
          }
          Delay_mS(10);
        }
        return(1);
    }
  }
  return(0);
}


unsigned char Keyvalue = 0 ; //用来记录按键的值
/***************************
//主函数
***************************/
void main(void)
{
 	Initial();  //调用初始化函数
        LED3 = 1; //点亮LED3
 	while(1)
 	{
           Keyvalue = KeyScan(); //读取按键值
           
           if(Keyvalue == 1) //短按
           {
              LED3 = !LED3;
           }; 
          
           if(Keyvalue == 11) //双击
           {
              LED4 = !LED4;
           };   
          
           if(Keyvalue == 111) //长按
           {
              LED1 = !LED1;
           };  
          Keyvalue = 0;
 	}
}
  • 19
    点赞
  • 80
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值