找回密码
 立即注册

QQ登录

只需一步,快速开始

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

关于单片机程序运行和中断处理的疑惑

[复制链接]
跳转到指定楼层
楼主
ID:258164 发表于 2018-11-28 13:38 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
今天在做按键的长短按的程序时,突然有了疑惑。
我的程序流程是:定时器每隔50ms定时一次,计数器标志加1,主程序中判断计数器的值,大于60表示按键按下到松开时间为3s,判定为长按。
主程序示例代码:
main(){
     ...
     ...
    while(1){
         if(按键按下){
                 开启定时器;
                 while(等待按键松开);
                 关闭定时器;

                 判断长短按;
          }

    }
}


我的疑惑是:假如我现在是1s的短按。我的定时中断程序50ms执行一次,我的主程序中在等待按键松开需要1s中,是不是说我的程序在这个地方一直等待1s?这时候我的单片机运行情况是什么样?
如果是一直等待中不干别的,那这种方法对单片机的利用效率也太低了吧。
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:434977 发表于 2018-11-28 14:59 | 只看该作者
按照你这样的代码,主程序就是这么执行的。
由于你哪个while(等待按键松开)语句,主程序会一直在这个循环执行,直到你按键松开,然后跳出循环,接着就是定时器关闭。
在定时器开始,到关闭,这段时间,定时器是一直以你定的频率运行的。
然后就是检测你的按键是否达到3s,按照你的描述,是不足3s的,判断为短按。
回复

使用道具 举报

板凳
ID:47286 发表于 2018-11-28 15:04 | 只看该作者
不能这么写吧 while会造成死等

如果 按键按下
并且 清零标记=0(防止反复清零计数器)
{
  如果 清零标记=0
  置位 清零标记
  清零 计数器变量(清零后累加的时间即按键按下的时间)
}

如果 清零标记=1
{
  如果 按键松开
{
   比较计数器值
  {
     如果 计数器<设定值
     {短按}
     否则
    {长按}
    清零 清零标记(可以再次清零)
   }
}
}

大概的逻辑顺序 用for和while的延时基本都是死等 会影响其它步骤工作 尤其是程序写大了 尽量养成少用这种方法的习惯吧 这方法多是初学为了容易理解 或者在不重要的地方做很短的延时才会用 你这成秒的等通常不这么搞
回复

使用道具 举报

地板
ID:426340 发表于 2018-11-28 15:23 来自手机 | 只看该作者
在这1s内你给它设定为等待按键松开了呀
回复

使用道具 举报

5#
ID:94031 发表于 2018-11-28 15:31 | 只看该作者
你不要 while(一直等待按键松开);而是50ms来读一次键状态,如果还在按下状态就继续计数,否则停止计数,这样除了读数,处理这段时间外,还可以干别的事。
回复

使用道具 举报

6#
ID:258164 发表于 2018-11-28 16:02 | 只看该作者
dzbj 发表于 2018-11-28 15:04
不能这么写吧 while会造成死等

如果 按键按下

感谢回答,我就是烦恼死等的问题,这样我的其他处理要等很长时间,对实际的应用来说是不能接受的。
但是你说的这种控制逻辑我还是不太明白,我怎么检测我的按键何时松开的呢?
回复

使用道具 举报

7#
ID:428685 发表于 2018-11-28 16:03 | 只看该作者
你好,可不可以把程序发出来。
回复

使用道具 举报

8#
ID:258164 发表于 2018-11-28 16:08 | 只看该作者
xuyaqi 发表于 2018-11-28 15:31
你不要 while(一直等待按键松开);而是50ms来读一次键状态,如果还在按下状态就继续计数,否则停止计数,这 ...

谢谢,这也是一种方法,有没有效率更高的方法呢,因为我的整个程序要做的事情很多,所以一个循环周期越短越好
回复

使用道具 举报

9#
ID:424805 发表于 2018-11-28 16:22 | 只看该作者
在短按一秒的时间内,你可以做其他事。但是你一直按就有问题了。程序没有处理好。
回复

使用道具 举报

10#
ID:401564 发表于 2018-11-28 17:28 | 只看该作者
非得是延时吗?
比如:按键按下一次,进行一次ADC,把ADC运行的时长当成是延时,又可以去抖动又可以延时,又不浪费MCU的时钟,还没有松开的话,再进行一次ADC,这不就节省资源了吗
回复

使用道具 举报

11#
ID:258164 发表于 2018-11-29 09:09 | 只看该作者
Y_G_G 发表于 2018-11-28 17:28
非得是延时吗?
比如:按键按下一次,进行一次ADC,把ADC运行的时长当成是延时,又可以去抖动又可以延时, ...

是这样的,我做的这个产品按键比较多,单片机资源有比较紧张,所以按键都是普通读IO口的方式。
回复

使用道具 举报

12#
ID:258164 发表于 2018-11-29 10:27 | 只看该作者
感谢各位的回答,在网上看到关于利用状态机处理按键的思想,觉得是个不错的方法,这里分享下
https://blog.csdn.net/xiaocheng_sky/article/details/52146083
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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