标题:
单片机单键长按,单击、双击及三击响应程序请教
[打印本页]
作者:
daiya
时间:
2020-5-30 15:25
标题:
单片机单键长按,单击、双击及三击响应程序请教
我要做一个警告灯小程序,需要单片机识别单按键,实现对长按,单击、双击及三击的响应,由于是初学,一点头绪也没有,请各位高人指导!另外还有要对各种按键响应程序融会贯通,需要掌握什么基础知识呢?
作者:
xianfajushi
时间:
2020-5-30 17:17
三击的响应?有单击 双击 长按可参:
https://blog.csdn.net/xianfajushi/article/details/82281411
作者:
gxslxxm
时间:
2020-5-30 22:22
初学啊。
简单说需要几点:
1:mcu的定时器设置、中断设置。
2:io口输入输出、读取。内部结构暂时不需要太深刻的理解。
3:基本的c51语言。
4:了解按键的消抖的问题。
5:因为你目前的功能,是对于上升沿、下降沿、的判断问题。可以考虑看看自己度娘下边的红字部分。吴坚鸿讲的东西嘛,干这行的普遍已经用到了的东西,可能没意识到或者不屑于将这种东西的问题,有人总结还是可以收藏看看的。
从业将近十年!手把手教你单片机程序框架(连载)
作者:
12356742
时间:
2020-5-31 17:09
#define key_state_0 0#define key_state_1 1#define key_state_2 2#define key_state_3 3 #define key_no 0#define key_click 1#define key_double 2#define key_long 3 #define key_input P30/***************************************************************************程序功能:一个按键的单击、双击、长按。三种按键方式,然后做不同的处理。 ***************************************************************************/ static unsigned char key_driver(void){ static unsigned char key_state_buffer1 = key_state_0; static unsigned char key_timer_cnt1 = 0; unsigned char key_return = key_no; unsigned char key; key = key_input; //read the I/O states switch(key_state_buffer1) { case key_state_0: if(key == 0) key_state_buffer1 = key_state_1; //按键被按下,状态转换到按键消抖和确认状态// break; case key_state_1: if(key == 0) { key_timer_cnt1 = 0; key_state_buffer1 = key_state_2; //按键仍然处于按下状态 //消抖完成,key_timer开始准备计时 //状态切换到按下时间计时状态 } else key_state_buffer1 = key_state_0; //按键已经抬起,回到按键初始状态 break; //完成软件消抖 case key_state_2: if(key == 1) { key_return = key_click; //按键抬起,产生一次click操作 key_state_buffer1 = key_state_0; //转换到按键初始状态 } else if(++key_timer_cnt1 >= 100) //按键继续按下,计时超过1000ms { key_return = key_long; //送回长按事件 key_state_buffer1 = key_state_3; //转换到等待按键释放状态 } break; case key_state_3: //等待按键释放 if(key == 1) //按键释放 key_state_buffer1 = key_state_0; //切回按键初始状态 break; } return key_return;} /***************************************************************************函数功能:中层按键处理函数,调用底层函数一次,处理双击事件的判断, 返回上层正确的无键、单击、双击、长按四种状态本函数由上层循环调用,间隔10ms***************************************************************************/unsigned char key_read(void){ static unsigned char key_state_buffer2 = key_state_0; static unsigned char key_timer_cnt2 = 0; unsigned char key_return = key_no; unsigned char key; key = key_driver(); switch(key_state_buffer2) { case key_state_0: if(key == key_click) { key_timer_cnt2 = 0; //第一次单击,不返回,到下个状态判断是否会出现双击 key_state_buffer2 = key_state_1; } else key_return = key; //对于无键、长按,返回原事件 break; case key_state_1: if(key == key_click) //又一次单击,时间间隔小于500ms { key_return = key_double; //返回双击事件,回到初始状态 key_state_buffer2 = key_state_0; } else if(++key_timer_cnt2 >= 50) { //这里500ms内肯定读到的都是无键事件,因为长按大于1000ms //在1s前底层返回的都是无键 key_return = key_click; //500ms内没有再次出现单击事件,返回单击事件
直接贴上源码
key_state_buffer2 = key_state_0; //返回初始状态 } break; } return key_return;}
————————————————
版权声明:本文为CSDN博主「沉默的小宇宙」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:
https://blog.csdn.net/qq997758497/java/article/details/80606710
作者:
渣渣馬
时间:
2020-5-31 23:03
#include<reg51.h>
sbit KEY=P1^0; //检测端口
int t0=0; //按键次数变量
void DelayMs(int x) //延时
{
int i;
while(x--) for(i=0;i<120;i++);
}
int KEY_SCAN(bit a) //按键检测
{
int t=0;
if(!a)
{
DelayMs(5);
while(!a) t=++t%50,DelayMs(50); //按键时长
t0=++t0%4; //按键次数
}
if(t0==1 && t<5) return 1; //单击
if(t0==2 && t<5) return 2; //双击
if(t0==3 && t<5) return 3; //三击
if(t>5) return 4; //长按
return 0;
}
void main()
{
int i=0,j=0;
while(1)
{
i=KEY_SCAN(KEY); //会进行覆盖
DelayMs(100);
j++;
if(j==20) t0=0; //长时间不按,清除按键次数为0
}
}
作者:
渣渣馬
时间:
2020-5-31 23:12
#include<reg51.h>
sbit KEY=P1^0;
int t0=0;
void DelayMs(int x)
{
int i;
while(x--) for(i=0;i<120;i++);
}
int KEY_SCAN(bit a)
{
int t=0;
if(!a)
{
DelayMs(5);
while(!a) t=++t%50,DelayMs(50); //按键的时长
t0=++t0%4;
}
if(t0==1 && t<5) return 1; //单击
if(t0==2 && t<5) return 2; //双击
if(t0==3 && t<5) return 3; //三击
if(t>5) return 4; //长按
return 0;
}
void main()
{
int i=0,j=0;
while(1)
{
i=KEY_SCAN(KEY); //按键返回的值会覆盖
DelayMs(100);
j++;
if(j==20) t0=0; //长时间不按键,清除按键次数
}
}
//希望有用,我也是新手!
复制代码
作者:
渣渣123
时间:
2020-6-1 09:12
用状态机
可以参考www点amobbs点com/thread-4991902-1-1.html
作者:
daiya
时间:
2020-6-2 18:01
本帖最后由 daiya 于 2020-6-3 10:45 编辑
5楼好奇妙的算法,似乎有问题,在实验板上实现不了
作者:
daiya
时间:
2020-6-3 10:33
渣渣馬 发表于 2020-5-31 23:12
我在实验板上试了,行不通,每次都由1击逐渐过渡到3击
作者:
Y_G_G
时间:
2020-6-3 19:37
你已经懂得看别人的算法了,那就自己写代码了,不要等别人的代码,这是不现实的,大多的只能给你一个参考意见或者直接复制一段代码给你,网上很多是没有真正验证过的
你先画个流程图,然后写代码,烧录验证,不要仿真
不行,改代码,烧录验证,不要仿真
再不行,再改代码,再烧录验证,不要仿真
再不行,再改代码.............
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1