当前位置:主页 > 查看内容

蓝桥杯单片机----独立按键的基本控制(长按、短按、双击)

发布时间:2021-08-11 00:00| 位朋友查看

简介:? ? ? ? 在CT107D单片机综合训练平台上首先将J5处的跳帽接到2~3引脚使按键S4~S7四个按键的另外一端接地从而成为4个独立键盘。在扫描按键的过程中发现有按键触发信号后先做去抖动处理当确认为按键按下时才进行相应的功能处理。 设计内容 ? ? ? ? 1.按下S7后抬……

? ? ? ? 在CT107D单片机综合训练平台上,首先将J5处的跳帽接到2~3引脚,使按键S4~S7四个按键的另外一端接地从而成为4个独立键盘。在扫描按键的过程中,发现有按键触发信号后,先做去抖动处理,当确认为按键按下时,才进行相应的功能处理。

设计内容:

? ? ? ? 1.按下S7后抬起,L1点亮,再次按下S7,L1熄灭;

? ? ? ? 2.长按S6,L2点亮,松开,L2熄灭;

? ? ? ? 3.双击S5,L3点亮;再次双击S5,L3熄灭;

? ? ? ? 4.按下S4,L4点亮,长按S4,L4熄灭。

? ? ? ? 设计之前,大家需要思考一下,什么是按键的短按、长按、双击,他们之间有什么联系,又有什么区别,简单点来说,短按就是你按键时长要小于一个时间点,比如你手把按键按下去时长要小于0.5秒,这个时候你可以把这个按键动作称为按键的短按,那相反把手按下按键大于0.5秒的按键动作可以理解为按键的长按,那双击又是什么呢?第一次按键按下后,在一段时间内这个按键又再次被按下,则称为双击,如果第二次按键过了这段时间,则表示未完成双击,当然,这段时间是大家自己定义的,下面就是利用这种思路,笔者写出了设计内容所要求的完整程序。

#include<stc15f2k60s2.h>

#define uchar unsigned char   //定义无符号字符类型uchar
#define uint unsigned int     //定义无符号整型类型uint

void delayms(int ms);          //延时函数
void allinit();                //初始化函数
void keyscan();                //独立按键程序
void Timer0Init(void);		     //1毫秒@12.000MHz	

uchar key_up=1;//按键按松开标志,按下时为0,松开时为1
uchar keytime=0; //按键计时	

uchar S7=0,S6=0,S5=0,key=0,cishu=0;
uint tt=0;
bit fla=0;

void main()//主函数
{
	allinit();                  //初始化函数
	Timer0Init();               //定时器初始化
	while(1)
	{
		keyscan();                //独立按键程序
	}
}
void keyscan()
{
	if(P30==0)       //判断P30是否等于0
	{
		delayms(5);    //延时5ms
		if(P30==0)     //再次判断P30是否等于0 
		{
			if(S7==0){S7=1;P2=0X80;P0&=0XFE;}              //标志位S7,用于判断L1灯亮灭状态,当S7=1时,L1亮
			else if(S7==1){S7=0;P2=0X80;P0|=0X01;}         //标志位S7,用于判断L1灯亮灭状态,当S7=0时,L1灭
		}
		while(!P30);   //如果按键不松开,则一直循环
	}
	else if(P31==0)  //判断P31是否等于0
	{
		delayms(5);    //延时5ms
		if(P31==0)     //再次判断P31是否等于0 
		{
			 S6=1;P2=0X80;P0&=0XFD;     //按键按下则S6置1,L2点亮
		}
	}
	else if((S6==1)&&(P31==1))      //判断按键是否为按下后松开状态
	{
		S6=0;P2=0X80;P0|=0X02;        //S6清零,L2熄灭
	}
	else if(P32==0)  //判断P32是否等于0
	{
		delayms(5);    //延时5ms
		if(P32==0)     //再次判断P32是否等于0 
		{
			if(S5==0)
			{
				S5=1;cishu++;EA=1;ET0=1;tt=0;   //第一次按键按下,S5标志位置1,按键次数+1,打开定时器开始计时
			}
			else if(S5==1)            //判断第二次按键是否按下
			{
				if((tt<=500)&&(cishu==1))   //判断按下时按键是否是在500ms以内按下,并且有过一次2按键按下记录
				{
					if(fla==0){fla=1;P2=0X80;P0&=0XFB;}          //标志位fla,用于判断L3灯亮灭状态,当fla=1时,L3亮
					else if(fla==1){fla=0;P2=0X80;P0|=0X04;}     //标志位fla,用于判断L3灯亮灭状态,当fla=0时,L3灭
					EA=0;ET0=0;tt=0;cishu=0;S5=0;   //关闭定时器,定时器按键时长tt清零,按键次数清零,S5标志位置0
				}
				else
				{
					EA=0;ET0=0;              //如果按键时长间隔大于500ms,则关闭定时器
					tt=0;cishu=0;S5=0;       //按键时长间隔tt清零,按键次数清零,S5标志位清零,便于下次按键记录
				}
			}
		}
		while(!P32);   //如果按键不松开,则一直循环
	}
	else if((key_up==1)&&(P33==0))  //判断按键是否按下
	{
		delayms(5);                   //延时5ms,消抖
		if(P33==0) key_up=0;          //再次判断按键是否按下,key_up清零,说明确实有按键按下
	}
	else if(P33==1)                 //程序为松手检测,所以在P33为1时判断按键状态
	{
		if(key_up==0)                 //判断key_up是否为0
		{
			key_up=1;                   //key_up置1,为下次按键记录做准备	
			if(keytime<50)              //判断按键计时是否小于500ms,即为短按
			{
				keytime=0;                //按键计时清零
				P2=0X80;P0&=0XF7;         //执行短按状态,让L4点亮
			}
			keytime=0;                  //按键计时清零
		}
	}
	if(key_up==0)//如果按键按下则按10ms时间计时
	{
		delayms(10);       //延时10ms
		keytime++;         //keytime++,用于在按键按下时有多少个10ms时间流过,方便判断按键长按短按
		if(keytime>=50)    //如果长按时间大于等于500ms则返回按键长按,在此处设置按键长按时长
		{
			P2=0X80;P0|=0X08; //执行长按状态,让L4熄灭
		}	
	}
}
void Timer0Init(void)		//1毫秒@12.000MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x20;		//设置定时初值
	TH0 = 0xD1;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
}
void time0() interrupt 1   //定时器0中断
{
	if(++tt==1200);          //定时器0计时
}
void delayms(int ms)//延时函数
{
	uint i,j;
	for(i=ms;i>0;i--)
		for(j=845;j>0;j--);
}
void allinit()//初始化函数
{
	P2=0XA0;P0=0X00;      //关闭蜂鸣器继电器
	P2=0X80;P0=0XFF;      //关闭所有LED灯
	
	P2=0XC0;P0=0XFF;      //选中所有数码管段选
	P2=0XFF;P0=0XFF;      //关闭所有数码管
}

?

;原文链接:https://blog.csdn.net/qq_45385706/article/details/115481123
本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!

推荐图文


随机推荐