? ? ? ? 在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; //关闭所有数码管
}
?
一石激起千层浪,继中国区浩浩荡荡的大裁员告一段落之后,甲骨文并未因此收起手...
计算属性computed: 支持缓存,只有依赖数据发生改变,才会重新进行计算 不支持...
本文将研究 ES6 的 for ... of 循环。 旧方法 在过去,有两种方法可以遍历 javas...
vbs:把一段文字中指定字符颜色变成红色的正则 functionc(Tstr,Word) Dimre Setre...
前言 相信大家都知道在IDE中代码的智能提示几乎都是标配,虽然一些文本编辑器也...
微信文件传输助手是微信电脑版与手机微信之间相互传输图片等文件的好工具,但很...
歌词编辑器 歌词编辑器 第一步:选择要播放的歌曲并播放 第二步:填写全部的歌词...
【排序算法】之lowb三人组冒泡、插入、选择 什么是lowb三人组 冒泡排序bubble so...
ADO对象: Connection Command Recordset Record Stream ASP支持的对象很多,可...
一、正则表达式概述 二、正则表达式在VBScript中的应用 三、正则表达式在VavaScr...