标题:
51单片机单按键多击程序修改
[打印本页]
作者:
daiya
时间:
2020-7-5 09:33
标题:
51单片机单按键多击程序修改
本帖最后由 daiya 于 2020-7-5 17:06 编辑
写了一个响应单按键多击的程序,按键弹起大于0.5S后返回键值,有问题,无法运行。可是我才疏学浅,找不到问题出在哪里。请各位高人帮忙看看问题出在哪?
#include <reg52.h>
sbit LED0 = P1^0;
sbit LED1 = P1^1;
sbit LED2 = P1^2;
sbit KEY1 = P3^2;
unsigned int count = 0,ClickFlag = 0,ClickFlagCount = 0,LongClickFlag = 0;
unsigned char i = 0,Click = 0;
unsigned char keynum = 0;
unsigned char keyscan(void)
{
if(KEY1)
{
if(count > 30 && count < 3000)
{
ClickFlag = 1;
keynum++;
}
count = 0;
if(ClickFlag == 1)
{
if(ClickFlagCount++ > 500)
{
ClickFlag = 0;
ClickFlagCount = 0;
return keynum;
keynum = 0;
}
else
{
ClickFlag = 0;
ClickFlagCount = 0;
}
}
else
{
ClickFlagCount = 0;
}
}
else
{
count++;
if(count > 3000)
count = 3001;
}
return 0;
}
void main()
{
EA = 1; //使能总中断
TMOD = 0x01; //设置T0为模式1
TH0 = 0xFC; //为T0赋初值0xFC67,定时1ms
TL0 = 0x67;
ET0 = 1; //使能T0中断
TR0 = 1; //启动T0
while (1)
{
if(i==1)
LED0 = ~LED0;
if(i==2)
LED1 = ~LED1;
if(i==3)
LED2 = ~LED2;
}
}
/* 定时器0中断服务函数 */
void InterruptTimer0() interrupt 1
{
TH0 = 0xFC; //重新加载初值
TL0 = 0x67;
i = keyscan();
}
作者:
xxpp2011
时间:
2020-7-5 12:09
本帖最后由 xxpp2011 于 2020-7-6 10:13 编辑
while(Key==0)//如果有按键按下
{ count=0;
while(Key==1)//等待按键弹起
{
if(Key==0)//如果按键再次按下
{
执行双击操作;
break;//结束循环
}
count++;//计数
if(count==100)//如果100个周期内无第二次按键则执行单击操作
{
执行单击操作;
break;//结束循环
}
}
if(count!=0)break;
}
作者:
daiya
时间:
2020-7-6 08:30
你给的程序只是双击按键,和我的程序的要求不同
作者:
Y_G_G
时间:
2020-7-6 08:51
哥们,你另一个帖子已经有几个人帮你了,有C,有汇编,有代码,有算法,有伪代码,就差帮你把所有代码写出来了
单击,双击,长按.短按,这是一个单片机按键应用非常入门的,相对简单的知识
这只是按键问题,用不到定时器的
按键按下之后是一定要去抖动的,可以是5mS的延时,然后,一边延时一边检测按键有没有松开,顺便记录松开的时间,用来判断是长按,短按,还是双击
你还要检测一下超过长按的时间,比如是一直按下那要怎么做...........
作者:
wulin
时间:
2020-7-6 08:51
按键初次按下开始计时,0.5s后输出键值1~3有效,超过3此按3次计。
#include <reg52.h>
sbit LED0 = P1^0;
sbit LED1 = P1^1;
sbit LED2 = P1^2;
sbit KEY1 = P3^2;
unsigned char count=0;
bit ClickFlag=0,Click=0;
unsigned char i = 0;
unsigned char keynum = 0;
unsigned int num;
void keyscan(void)
{
if(!KEY1)
{
if(++count>10 && ClickFlag==0)
{
ClickFlag=1;
Click=1;
if(keynum<3)
keynum++;
}
}
else
{
count=0;
ClickFlag=0;
}
}
void main()
{
TMOD= 0x01;
TL0 = 0x18; //1毫秒@12.000MHz
TH0 = 0xFC;
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能T0中断
EA = 1; //使能总中断
while (1)
{
if(i>0)
{
if(i==1)
LED0 = ~LED0;
if(i==2)
LED1 = ~LED1;
if(i>=3)
LED2 = ~LED2;
i=0;//清0
}
}
}
/* 定时器0中断服务函数 */
void InterruptTimer0() interrupt 1
{
TL0 = 0x18;
TH0 = 0xFC;
keyscan();
if(Click)//开始计时
{
num++;
if(num>=500)//0.5s
{
num=0; //清0
i=keynum;//取键值
keynum=0;//键值清0
Click=0; //停止计时
}
}
}
复制代码
作者:
笨笨兔
时间:
2020-7-6 09:03
unsigned char keyscan(void)
只是看到逻辑混乱啊。。。。。。
作者:
daiya
时间:
2020-7-6 11:16
我添加了注释,不知道可不可以看清楚逻辑了?
unsigned char keyscan(void)
{
if(KEY1)
{
if(count > 30 && count < 3000) //如果按下时间30ms~3s,认为是单击
{
ClickFlag = 1; //按键抬起标志置1
keynum++; //键号加1
}
count = 0; // 键按下时间计数器清0
if(ClickFlag == 1) //如果按键抬起标志为1
{
if(ClickFlagCount++ > 500) //按键抬起时间大于0.5s
{
ClickFlag = 0; //按键抬起标志清0
return keynum; //返回键号
keynum = 0; //键号清0
}
else //按键抬起时间小于0.5s
{
ClickFlag = 0;
}
}
else //如果按键抬起标志为0
{
ClickFlagCount = 0; //清0按键抬起时间计数器
}
}
else
{
count++; //按键按下时间计数器加1
if(count > 3000) //防止数据溢出
count = 3001;
}
return 0;
}
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1