标题: 为什么尽量在单片机中断函数中不要使用延时? [打印本页]

作者: vhantes    时间: 2018-5-15 19:04
标题: 为什么尽量在单片机中断函数中不要使用延时?
为什么尽量在单片机的中断函数中不要使用延时 ,我们老师这样说了,但还没告诉我们原因
我们现在开始接触单片机,还不清楚后面的知识。为什么尽量不要用延时呢 求问各位大佬

作者: jim.zhu    时间: 2018-8-31 08:38
使用延时导致整体的效率变低,相当于机器在空转,没有做任何事,空转的这段时间可以去干其他的事情
作者: 蓝天清野    时间: 2018-8-31 11:07
CPU利用率降低,代码执行周期较长!
作者: 大盘鸡    时间: 2018-8-31 16:08
中断等级比较高,CPU会优先处理中断,延时有点浪费资源
作者: gpzmvp    时间: 2018-8-31 16:36
中断其实就是让你mcu临时干一下别的工作,中断函数越精简,程序理论效率越高。以后接触到操作系统你就会有深入的体会。
作者: somayboy    时间: 2018-8-31 17:19
51黑电子是个好的学习网站,帮助了我很多     谢谢
作者: admin    时间: 2018-8-31 17:21
somayboy 发表于 2018-8-31 17:19
51黑电子是个好的学习网站,帮助了我很多     谢谢

不要发与提问无关的内容,这样会影响到
作者: scbin    时间: 2018-8-31 18:17
中断触发时会跳进中断中执行,而主函数中的程序会压入堆栈中停止执行。如果主函数中程序很短,中断执行的时间可以长。具体的需要根据所要实现的具体功能而定,机器是死的,人是活的。
作者: angmall    时间: 2018-8-31 18:53
通常在中断子程序中是不调用延时子程序的,这样会增加中断处理时间,如果有其它低级中断了,就会延误响应中断了。

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


作者: 昆明路口卖提莫    时间: 2018-8-31 19:27
杜绝纯延时 ,如果代码多的话  完全是浪费时间,小的程序或许不明显,但是假如你将来做大一点的程序的话 弊病就显示出来了,浪费cpu   用定时器中断就比较好了
作者: angmall    时间: 2018-8-31 19:32
尽量在单片机中断函数中不要使用延时,如果调用延时函数。 如果延时函数时间过长,则下次中断有可能不会被触发,类似按键不灵敏,还有可能因为中断和主程序都在使用延时函数,而和此相关的寄存器的值没有保存,导致延时时间出错。

作者: sgj511285515    时间: 2018-8-31 22:28
不光是中断,就是任务中,一般都不要用过长的delay,时间长  可以用定时器,在定时器中设置变量,在程序中查询,用了过多delay,这个叫阻塞了,而且中断有优先级,如果高优先级的中断中,使用了延时函数,低中断可能会遗漏
作者: psuxaog    时间: 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. }
复制代码
除了以上两种方式,也可以在赋值前关中断,赋值后开中断的方式,不会不推荐这样方式,容易导致时基不准。




作者: bxulaoshu123    时间: 2018-10-21 12:50
中断里面加了延时的话,会导致下一个中断不能及时响应
作者: xieyuhang66666    时间: 2018-10-21 13:48
因为没有必要,反而增加了系统负担,增加了处理时间。
作者: 296474491    时间: 2018-10-21 13:58
中断子程序中不要写调用延时子程序,中断子程序也不要写得过长,处理过多的任务,要尽快处理后及时返回,如果中断一次有很多任务需要执行完全,可以在中断子程序中设置一个标志位,在主程序中查这个标志位,当标志为1时,就在主程序中完成这些任务,这样就不会影响其它中断源的中断,也不会使中断产生混乱。

作者: 虚幻大千    时间: 2018-10-21 16:48
中断容易产生混乱




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1