找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 19767|回复: 16
收起左侧

为什么尽量在单片机中断函数中不要使用延时?

  [复制链接]
ID:330668 发表于 2018-5-15 19:04 | 显示全部楼层 |阅读模式
为什么尽量在单片机的中断函数中不要使用延时 ,我们老师这样说了,但还没告诉我们原因
我们现在开始接触单片机,还不清楚后面的知识。为什么尽量不要用延时呢 求问各位大佬
回复

使用道具 举报

ID:155507 发表于 2018-8-31 18:53 | 显示全部楼层
通常在中断子程序中是不调用延时子程序的,这样会增加中断处理时间,如果有其它低级中断了,就会延误响应中断了。

所以,中断子程序中不要写调用延时子程序,中断子程序也不要写得过长,处理过多的任务,要尽快处理后及时返回,如果中断一次有很多任务需要执行完全,可以在中断子程序中设置一个标志位,在主程序中查这个标志位,当标志为1时,就在主程序中完成这些任务,这样就不会影响其它中断源的中断,也不会使中断产生混乱。

评分

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

查看全部评分

回复

使用道具 举报

ID:389283 发表于 2018-8-31 08:38 | 显示全部楼层
使用延时导致整体的效率变低,相当于机器在空转,没有做任何事,空转的这段时间可以去干其他的事情
回复

使用道具 举报

ID:391903 发表于 2018-8-31 11:07 | 显示全部楼层
CPU利用率降低,代码执行周期较长!
回复

使用道具 举报

ID:391335 发表于 2018-8-31 16:08 | 显示全部楼层
中断等级比较高,CPU会优先处理中断,延时有点浪费资源
回复

使用道具 举报

ID:392046 发表于 2018-8-31 16:36 | 显示全部楼层
中断其实就是让你mcu临时干一下别的工作,中断函数越精简,程序理论效率越高。以后接触到操作系统你就会有深入的体会。
回复

使用道具 举报

ID:34853 发表于 2018-8-31 17:19 | 显示全部楼层
51黑电子是个好的学习网站,帮助了我很多     谢谢
回复

使用道具 举报

ID:1 发表于 2018-8-31 17:21 | 显示全部楼层
somayboy 发表于 2018-8-31 17:19
51黑电子是个好的学习网站,帮助了我很多     谢谢

不要发与提问无关的内容,这样会影响到
回复

使用道具 举报

ID:392085 发表于 2018-8-31 18:17 | 显示全部楼层
中断触发时会跳进中断中执行,而主函数中的程序会压入堆栈中停止执行。如果主函数中程序很短,中断执行的时间可以长。具体的需要根据所要实现的具体功能而定,机器是死的,人是活的。
回复

使用道具 举报

ID:367460 发表于 2018-8-31 19:27 | 显示全部楼层
杜绝纯延时 ,如果代码多的话  完全是浪费时间,小的程序或许不明显,但是假如你将来做大一点的程序的话 弊病就显示出来了,浪费cpu   用定时器中断就比较好了
回复

使用道具 举报

ID:155507 发表于 2018-8-31 19:32 | 显示全部楼层
尽量在单片机中断函数中不要使用延时,如果调用延时函数。 如果延时函数时间过长,则下次中断有可能不会被触发,类似按键不灵敏,还有可能因为中断和主程序都在使用延时函数,而和此相关的寄存器的值没有保存,导致延时时间出错。
回复

使用道具 举报

ID:391754 发表于 2018-8-31 22:28 | 显示全部楼层
不光是中断,就是任务中,一般都不要用过长的delay,时间长  可以用定时器,在定时器中设置变量,在程序中查询,用了过多delay,这个叫阻塞了,而且中断有优先级,如果高优先级的中断中,使用了延时函数,低中断可能会遗漏
回复

使用道具 举报

ID:405708 发表于 2018-10-21 11:27 | 显示全部楼层
本帖最后由 psuxaog 于 2018-10-21 11:42 编辑

如果你用定时中断置标志位,主程序查询标志位的情况,如果中断中有延时,且大于定时时间,此时会出现主程序无法执行的情况,如果有用到看门狗,单片机会重复复位,即使没有看门狗,主程序中的程序不运行也是要命的。
      中断中用的变量也是有讲究的,比如以下情况:
      下面的代码中gValTmp是16位变量,TMP_Process是主循环中的程序,51单片机是8位机,给gValTmp赋值的时候是一个字节是个字节处理的,16位是两个字节,如果已经处理了第一个字节的时候发生了中断,那中断中的gValTmp的值就不是正常的值(另一个字节没有刷新呀),会导致数据错乱。
  1. u16 gValTmp = 0;
  2. void TIM0_IRQ interrupt IRQ_T0
  3. {
  4.     TL0 = XXX;
  5.     TH0 = XXX;
  6.     TMP_SendData(gValTmp);
  7. }
  8. void TMP_Process(void)
  9. {
  10.     gValTmp = TMP_GetValue();
  11. }


复制代码
将以上代码稍作修改,这个问题就可以解决了:

  1. u16 gValTmp = 0;
  2. bit gFlagUpdated = 0;
  3. void TIM0_IRQ interrupt IRQ_T0
  4. {
  5.     TL0 = XXX;
  6.     TH0 = XXX;
  7.     if(gFlagUpdated)
  8.     {
  9.         gFlagUpdated = 0;
  10.         TMP_SendData(gValTmp1);
  11.     }
  12. }
  13. void TMP_Process(void)
  14. {
  15.     gValTmp = TMP_GetValue();
  16.     gFlagUpdated = 1;
  17. }
复制代码
除了以上两种方式,也可以在赋值前关中断,赋值后开中断的方式,不会不推荐这样方式,容易导致时基不准。



回复

使用道具 举报

ID:413031 发表于 2018-10-21 12:50 | 显示全部楼层
中断里面加了延时的话,会导致下一个中断不能及时响应
回复

使用道具 举报

ID:413081 发表于 2018-10-21 13:48 | 显示全部楼层
因为没有必要,反而增加了系统负担,增加了处理时间。
回复

使用道具 举报

ID:413082 发表于 2018-10-21 13:58 | 显示全部楼层
中断子程序中不要写调用延时子程序,中断子程序也不要写得过长,处理过多的任务,要尽快处理后及时返回,如果中断一次有很多任务需要执行完全,可以在中断子程序中设置一个标志位,在主程序中查这个标志位,当标志为1时,就在主程序中完成这些任务,这样就不会影响其它中断源的中断,也不会使中断产生混乱。
回复

使用道具 举报

ID:413154 发表于 2018-10-21 16:48 | 显示全部楼层
中断容易产生混乱
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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