找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2232|回复: 18
打印 上一主题 下一主题
收起左侧

求助:单片机单按键功能修改成长短按键功能程序问题

[复制链接]
跳转到指定楼层
楼主
ID:137005 发表于 2021-7-4 22:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
各位好!
  请教一下,单按键功能修改成长短按功能不生功能,问题出在哪里?
单按键功能代码如下:
void keyscan() //按键扫描
{
        if((IN_1==0)&&(bz1==0)){bz1=1;k1=1;}
        if((IN_1==1)&&(bz1==1)){bz1=0;k1=1;}

}


修改成长短按键功能代码如下:
void keyscan() //按键扫描
{
        static unsigned int key_press_time = 0;  // ……请记得标为静态变量
    if((IN_1==0)&&(bz1==0))
        {
        if(++key_press_time <=0 ) --key_press_time;//计量按键时间,并避免数据溢出
        if(key_press_time==1500){
            bz1=1;k2=1;//新增功能,按键长按3s时要做的事情;
        }
    }
        else
        {
        if(20<=key_press_time && key_press_time < 1500){
            bz1=1;k1=1;//大于20ms小于3s,视为短按
        }
        key_press_time=0;
    }
        if((IN_1==1)&&(bz1==1)){bz1=0;k1=1;}
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:213173 发表于 2021-7-5 07:23 | 只看该作者
#define d 250//按实际需要定义数值
#define c 50*d

void keyscan() //按键扫描
{
        static unsigned int key_press_time = 0;  //静态变量
        if(IN_1)//松手
        {
                if(key_press_time > d && key_press_time < c)
                {
                        bz1=1;k2=1;//短按任务
                }
                key_press_time = 0;
        }
        else //按下
        {
                key_press_time++;
                if(key_press_time == c)
                {
                        bz1=1;k1=1;//长按任务
                }
                if(key_press_time>c)
                        key_press_time = c+1;//防止溢出
        }
}
回复

使用道具 举报

板凳
ID:137005 发表于 2021-7-5 08:00 | 只看该作者
wulin 发表于 2021-7-5 07:23
#define d 250//按实际需要定义数值
#define c 50*d

谢谢!晚上回去试试。
回复

使用道具 举报

地板
ID:161164 发表于 2021-7-5 08:29 来自手机 | 只看该作者
wulin 发表于 2021-7-5 07:23
#define d 250//按实际需要定义数值
#define c 50*d


有什么问题?要我们推理出来吗?
女子口巴,閒的发慌,我就推一推
void keyscan() //按键扫描
{
        if((IN_1==0)&&(bz1==0)){bz1=1;k1=1;}//这是按下吧?
        if((IN_1==1)&&(bz1==1)){bz1=0;k1=1;}//这是放开吧?
}
发现k1=1出现了两次
由于短按时间短,所以只当作用一次也沒什么

void keyscan() //按键扫描
{
        static unsigned int key_press_time = 0;  // ……请记得标为静态变量
    if((IN_1==0)&&(bz1==0))
        {
        if(++key_press_time <=0 ) --key_press_time;//计量按键时间,并避免数据溢出
        if(key_press_time==1500){
            bz1=1;k2=1;//新增功能,按键长按3s时要做的事情;
        }
    }
        else
        {
        if(20<=key_press_time && key_press_time < 1500){
            bz1=1;k1=1;//大于20ms小于3s,视为短按
        }
        key_press_time=0;
    }
        if((IN_1==1)&&(bz1==1)){bz1=0;k1=1;}
}
新代码又发现k=1出现了两次
这次不能当没事发生了
当长按之后(k2=1)一放开,k1=1又来了
不知道k2=1和k1=1所代表的意义有没有冲突
但我建议把最后一句改为:
if((IN_1==1)&&(bz1==1)){bz1=0;}

当然,如果你只求一个可用的代码
就直接用二楼的吧~

评分

参与人数 1黑币 +5 收起 理由
ax6808 + 5

查看全部评分

回复

使用道具 举报

5#
ID:137005 发表于 2021-7-5 08:59 | 只看该作者
本帖最后由 molo 于 2021-7-5 09:25 编辑
wulin 发表于 2021-7-5 07:23
#define d 250//按实际需要定义数值
#define c 50*d

单片机是STC8F2K16S,频率11.0592,测试了一下,无论长短按,都是长按的结果。
回复

使用道具 举报

6#
ID:137005 发表于 2021-7-5 09:10 | 只看该作者
lkc8210 发表于 2021-7-5 08:29
有什么问题?要我们推理出来吗?
女子口巴,閒的发慌,我就推一推
void keyscan() //按键扫描

K1,K2是按钮操作后,发送不同命令参数。按下的K1,K2写好了,但松开后的还没写,临时用了K1
回复

使用道具 举报

7#
ID:81196 发表于 2021-7-5 09:21 | 只看该作者
一般,我做这个长按短按,结合定时器做,这样可以记录到每个那件按下的时间长度及触发长按的时间设置,不同时间对应不同的效果.
回复

使用道具 举报

8#
ID:137005 发表于 2021-7-5 09:41 | 只看该作者
shumivan 发表于 2021-7-5 09:21
一般,我做这个长按短按,结合定时器做,这样可以记录到每个那件按下的时间长度及触发长按的时间设置,不同时间 ...

void keyscan() //按键扫描
{
        if((IN_1==0)&&(bz1==0)){bz1=1;k1=1;}
        if((IN_1==1)&&(bz1==1)){bz1=0;k1=1;}

}
以上这部分代码在程序中运行是可以的。只是想增加功能,区分长按和短按。
我自己写了一个,有问题,求助怎么把原来程序修改增加长、短按功能。
回复

使用道具 举报

9#
ID:123289 发表于 2021-7-5 09:52 | 只看该作者
要点:
1、按下时间的界定值,不要直接用常数,而用变量AN,将界定值放入AN,这样只要改变AN中的数值就达成目的了。
2、制作的一个计时器,统计按下的时间。不要用DELAY,死板,且不能解决中途停按,可长按超时(按了20秒,你认为按了一次还是多次)。
3、确定:计时的起点,这是要点。
4、确定:计时的终点,这是要点。(建议:1、弹起时结束计时;2、计时超限时计时器不再计数)
5、比较计器计时终点值与AN的大小,就达成目的了。


回复

使用道具 举报

10#
ID:161164 发表于 2021-7-5 11:55 | 只看该作者
molo 发表于 2021-7-5 09:10
K1,K2是按钮操作后,发送不同命令参数。按下的K1,K2写好了,但松开后的还没写,临时用了K1

所以你的问题是什么?
我的推理正确吗?
回复

使用道具 举报

11#
ID:213173 发表于 2021-7-5 16:31 | 只看该作者
molo 发表于 2021-7-5 08:59
单片机是STC8F2K16S,频率11.0592,测试了一下,无论长短按,都是长按的结果。

这是按标准51/12T写的,你用1T单片机,这句你没有理解:#define d 250//按实际需要定义数值,扩大10倍试试。
回复

使用道具 举报

12#
ID:213173 发表于 2021-7-5 18:14 | 只看该作者
molo 发表于 2021-7-5 08:59
单片机是STC8F2K16S,频率11.0592,测试了一下,无论长短按,都是长按的结果。

这个简单按键长短按程序适合放在主函数周期相对稳定的环境运行,短按消抖时间和长按时间的计数值是以主函数周期计算的。
回复

使用道具 举报

13#
ID:213173 发表于 2021-7-5 19:09 | 只看该作者
molo 发表于 2021-7-5 09:41
void keyscan() //按键扫描
{
        if((IN_1==0)&&(bz1==0)){bz1=1;k1=1;}

你的按键功能需求可以在这程序中找到
4位数码管时钟温度表仿真.zip (228.25 KB, 下载次数: 9)

回复

使用道具 举报

14#
ID:137005 发表于 2021-7-6 08:01 | 只看该作者
wulin 发表于 2021-7-5 19:09
你的按键功能需求可以在这程序中找到

谢谢!
回复

使用道具 举报

15#
ID:140489 发表于 2021-7-8 10:32 | 只看该作者
去看看吴坚鸿的教程,会有意想不到的收获
回复

使用道具 举报

16#
ID:140489 发表于 2021-7-8 10:45 | 只看该作者
你看看这个帖子,有吴坚鸿教程的PDF文档,http://www.51hei.com/bbs/dpj-55036-1.html

评分

参与人数 1黑币 +5 收起 理由
ax6808 + 5 已下载,拜读了,其中不少实战经验.

查看全部评分

回复

使用道具 举报

17#
ID:137005 发表于 2021-7-8 11:02 | 只看该作者
lids 发表于 2021-7-8 10:45
你看看这个帖子,有吴坚鸿教程的PDF文档,http://www.51hei.com/bbs/dpj-55036-1.html

好的,我看看。
原来那2句挻好用的,增加了长短按,试了很多长程序,感觉短按没有原来的好用一样,再努力学习改进,谢谢分享。
void keyscan() //按键扫描
{
        if((IN_1==0)&&(bz1==0)){bz1=1;k1=1;}
        if((IN_1==1)&&(bz1==1)){bz1=0;k1=1;}

}
回复

使用道具 举报

18#
ID:137005 发表于 2021-9-26 13:54 | 只看该作者
如附件红色圈这种金属按钮,按键检测异常。

an.zip

121.48 KB, 下载次数: 5

回复

使用道具 举报

19#
ID:975054 发表于 2022-11-29 18:54 | 只看该作者
我近日搞了个最简stc8(SOP8脚)+单按键监控小系统,1脚接按键,1脚接充电检测,剩余4脚控制N种运行模式(如接4种LED),单节锂电池供电无需外加LDO降压,就可直接利用内部电源监控电压(电池电量,省1脚),目前首选方案比较简单:按键直接用复位脚(P54),工作时用EEPR记录复位次数(N次归0),按1次复位1次改变1种工作模式(N次归0,待机模式极其省电,才3μA),代码主要多了EEPR标准代码,其余代码极其简单可靠.
有空我再研究一下利用中断监控长短按的优缺点(优点:主要想实现长按可靠进入待机状态,短按改模式),力求简单可靠.
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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