找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2037|回复: 5
收起左侧

单片机旋转彩虹灯在运行时按键无反应

[复制链接]
回帖奖励 8 黑币 回复本帖可获得 1 黑币奖励! 每人限 1 次
ID:565305 发表于 2020-5-19 18:14 | 显示全部楼层
从你现在代码结构来看:

    在 delay(1) 的 for(i=0;i<n;i++) 前面,要改几个局部变量为全局变量,并且加入按键判断的那段逻辑代码(改成函数形式),还要【状态变更】。

    当然,可能会觉得,没必要每次都判断按键啊, 所以,判断按键的时机,也有几种选择:

    # 在 delay(1) 中加全局计数器,当满某计数 CountMax 后,例如 CountMax=50 ms 就处理一次按键并【状态变更】一次
     (从目前代码看后续显示有大量 delay1() 函数)
      假设 n 大于了 CountMax 怎么处理? 简单,目前代码中,可以用 10ms 为一个单位,
      延迟 100 毫秒就相当于循环 10 次 10ms,会触发 CountMax>=50ms 两次。
      当然,这种方法,因为代码执行耗费时间长度不一样,计时会有偏差。

   # 或者,每轮 for(;m>=0;m--) / for(;m<=7;m++) 之后,再才读取按键并【状态变更】一次,当然这种会丢按键。
      一般来说,每一次按键,大概会有 60ms 以上 ,折算最高每秒按 15 下按键,一般人按 12  13 下最多了

   # 又或者在计时器中断上,每隔 XX 毫秒 读取按键消息(做个记录), 然后在 delay1() 中处理该消息,再进行【状态变更】。

   注:【状态变更】,包含强行退出 每轮 for(;m>=0;m--) / for(;m<=7;m++) 的循环结构的标志处理。
         简单点,可以让 delay1 返回值来做这样的判断 ,例如  for(...){  if(delay1(n)!=0) break;  ... }; 或者做个全局标志也行;
         同时,还要留存一些变量防止每次换状态后,灯从头跑起。

另外也有一些方法,比方说,灯的更新动作在定时器中断上(定时器中断代码内不写 delay 了),由按键改了 speed 或者灯态的值 → 换算并修订下次中断时间或者使能中断 。这种改法要防止中断重入、做消息处理以及变量规划等,细节比较多就不展开了。(反过来,按键更新,在定时器中断上做也行啊,就是灯方向处理)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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