找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 23650|回复: 10
收起左侧

51单片机按键检测源程序(实现单击、双击、长按等功能)

  [复制链接]
ID:280994 发表于 2018-8-6 14:11 | 显示全部楼层 |阅读模式
原理:将按键这一事件的过程划分成如下几个状态:
        //stata 函数运行状态
        //0: 初始状态
        //1: 第一洗按键按下
        //2: 第一次长按抬起
        //3: 第一次短按抬起
        //4: 第二次按键按下
        //5: 第二次按键抬起

利用定时器记录系统运行时间,根据系统运行时间来确定按键时间间隔,根据不同的时间间隔来判断当前按键事件处于哪一过程以及是否结束该事件。
主函数中应循环调用按键检测函数,调用间隔不超过100ms,此函数不会阻塞程序运行。


版本说明:
............................................................
版本号Beta0.0
本驱动工具包主要包含以下驱动(xxx.c文件和xxx.h文件共同使用,下面不再写后缀)
1“define.h”----包含了类型定义与开发板属性的设置(如晶振频率等)
2“delay”----定义了两个延时函数,支持STC大多数芯片(除15H系列..)
【提示】本函数库中驱动多数依赖于"delay.c""delay.h"和"define.h"文件
3“digital_display”----数码管显示驱动(硬件是基于两个373锁存器分别用作段数据和位数据)
4“digital_to_string”----包含了浮点数转换成字符串的函数
5“DS18B20”----温度传感器驱动
6“DS1302”----时钟芯片驱动
7“I2C”----软件模拟I2C总线驱动
8“Keyboard”----矩阵键盘驱动
9“LCD_1602_display”----1602液晶屏驱动(并口)
10“LCD_12864_display”----12864液晶屏驱动(并口带中文字库)(只是显示文字,不包含画图)
11“NEC_IR_coding”----用一个红外LED实现红外编码发射的驱动
12“NEC_IR_decoding”----红外解码驱动
13“NRF24L01”----2.4G无线通讯模块驱动
14“Uart”----串口驱动相关函数   
未完待续...
............................................................
............................................................
版本号Beta0.1
修复了数码管有关残影的bug
取消了矩阵键盘的松手检测,检测不到键按下时返回0代替
未完待续...
............................................................
............................................................
版本号Beta0.2
加入了独立按键的检测,兼容矩阵按键,修复了矩阵键盘关于不同开发板兼容性的bug
增加了串口不同波特率的初始化程序
未完待续...
............................................................
............................................................
版本号Beta0.3
调整了数码管显示驱动的结构代码,方便不同开发板移植
调整了红外解码阈值,提高解码效率
未完待续...
............................................................
............................................................
版本号Beta0.4
1602液晶驱动的代码更改为区域刷新,字符串长度不够显示空格,避免出现显示残留
调整了若干驱动文件名字
修复了数字转字符串函数在显示0时有负号的bug
添加了QMC5883地磁场传感器驱动
未完待续...
............................................................



核心代码如下:


/*
按键检测
返回值:0  无结果
                1  短按
                2  长按
                3  双击
*/
u8 key_scan()
{
        //stata 函数运行状态
        //0: 初始状态
        //1: 第一洗按键按下
        //2: 第一次长按抬起
        //3: 第一次短按抬起
        //4: 第二次按键按下
        //5: 第二次按键抬起
        u8 res=0;
        static u8 key_sta,stata=0;  
        static u32 time=0,time1=0,time2=0;
        if(key==0)        //按下消抖
        {
delay_10ms(1);
                if(key==0)        
                        key_sta=0;               
                else
                        return 0;
        }
        else //松开消抖
        {
                delay_10ms(1);
                if(key==1)         
                        key_sta=1;               
                else
                        return 0;               
        }

        if(stata==0)                                 //0: 初始状态
        {         
                if(key_sta==0)                  
                {
                        stata=1;
                        time=system_time;
                }
                return 0;
        }
        else if(stata==1)                        //1: 第一洗按键按下
        {
                time1=system_time;
                time2=time1-time;         
                if(time2>60)
                {
                        stata=2;        
                }
                else if(key_sta==1)
                {
                        time=system_time;
                        stata=3;
                }
                return 0;
        }
        else if(stata==2)                        //2: 第一次长按抬起
        {
                if(key_sta==1)
                {        
                        stata=0;
                        return 2;        
                }
                return 0;
        }
        else if(stata==3)                        //3: 第一次短按抬起
        {
                   time1=system_time;
                time2=time1-time;
                if(time2>30)
                {
                        stata=0;        
                        return 1;
                }
                else if(key_sta==0)
                {        
                        stata=4;        
                }
                return 0;
        }
        else if(stata==4)                        //4: 第二次按键按下
        {
                if(key_sta==1)                        //5: 第二次按键抬起
                {
                        stata=0;
                        return 3;
                }
                return 0;
        }
        else
                return 0;
}
void time0_irq() interrupt 1 using 1        //系统时间定时器  10ms+1
{
         TL0 = 0x00;                //设置定时初值
        TH0 = 0xDC;                //设置定时初值
        system_time++;
}



说明:该工程使用了STC头文件,请在STC-ISP软件中将头文件添加到Keil

截图.jpg

全部资料51hei下载地址:
按键.rar (63.3 KB, 下载次数: 306)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:438987 发表于 2018-12-7 11:01 | 显示全部楼层
可以是可以,但是,跟组合按键有冲突吗
回复

使用道具 举报

ID:256970 发表于 2019-7-16 15:09 | 显示全部楼层
还没有试用此程序,单就按键程序来说挺好的!思路很清晰!
回复

使用道具 举报

ID:207882 发表于 2019-7-16 21:52 | 显示全部楼层
        while(time2<t)
        {
                time2=system_time-time1;
        }


你这里还是死等10ms中断一次呀,,,还是逃不出delay或者while的魔爪,,哈哈,,
回复

使用道具 举报

ID:387856 发表于 2020-6-29 09:05 | 显示全部楼层
一个程序里只要用到了delay(),这个程序就是适合玩玩,做不了产品的。真正的程序里一般不会用到delay()的。
回复

使用道具 举报

ID:502376 发表于 2020-9-28 11:30 | 显示全部楼层
liuhailan5757 发表于 2020-6-29 09:05
一个程序里只要用到了delay(),这个程序就是适合玩玩,做不了产品的。真正的程序里一般不会用到delay()的。

写入1602屏幕的时候,不用delay怎么办  延时几us也要定时器吗
回复

使用道具 举报

ID:492091 发表于 2020-10-9 14:21 | 显示全部楼层
登录只为点赞,谢谢
回复

使用道具 举报

ID:118488 发表于 2021-6-8 09:19 | 显示全部楼层
kankan,xiexie~
回复

使用道具 举报

ID:401564 发表于 2021-7-8 00:38 | 显示全部楼层
liuhailan5757 发表于 2020-6-29 09:05
一个程序里只要用到了delay(),这个程序就是适合玩玩,做不了产品的。真正的程序里一般不会用到delay()的。

虽然过了一年多了,但我不是忍不住要说说
"一个程序里只要用到了delay(),这个程序就是适合玩玩,做不了产品的。真正的程序里一般不会用到delay()的。
"
真正的有经验的单片机工程师是不会说这种话的,
我虽然才学C语言几天,但我手头上有公司以前留下的档案,产品是出口德国的,已经稳定量产的程序,看了你这话我特意的去看一下,delay()是有很多的
回复

使用道具 举报

ID:65956 发表于 2021-7-9 09:07 | 显示全部楼层
你这个system_time是全局变量吗?在上面的代码找不到定义处
回复

使用道具 举报

ID:974137 发表于 2021-11-15 14:51 | 显示全部楼层
Y_G_G 发表于 2021-7-8 00:38
虽然过了一年多了,但我不是忍不住要说说
"一个程序里只要用到了delay(),这个程序就是适合玩玩,做不了产 ...

很好的学习环境啊
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表