极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 14269|回复: 5

关于外部中断中使用延时

[复制链接]
发表于 2014-11-18 09:41:22 | 显示全部楼层 |阅读模式
如何在中断程序中实现延时功能呢?
像delay()等延时函数在中断程序中是不可用的。

我想实现一个点灯的延时程序,通过中断pin 2去控制pin 13点灯,当按下pin 2时灯亮一秒,然后灭掉。
pin 2被上拉,当按下按钮时,pin 2直接接地。

程序如下:无法实现我需要的功能

  1. int pin = 13;


  2. void setup()
  3. {
  4.   pinMode(pin,OUTPUT);
  5.   Serial.begin(9600);
  6.   attachInterrupt(0,blink,FALLING);
  7. }

  8. void loop()
  9. {
  10.   digitalWrite(pin,LOW);
  11. }

  12. void blink()
  13. {
  14.   unsigned long time,time1;
  15.   time=millis();
  16.   for(time1=time;(time1-time)<1000;time1=millis())
  17.   {
  18.    digitalWrite(pin,HIGH);
  19.   }
  20.   digitalWrite(pin,LOW);
  21. }
复制代码
回复

使用道具 举报

发表于 2014-11-18 11:54:15 | 显示全部楼层
官網清楚說明, ISR 中不應該用 delay() 及 millis() 的.

Generally, an ISR should be as short and fast as possible. If your sketch uses multiple ISRs, only one can run at a time, other interrupts will be ignored (turned off) until the current one is finished. as delay() and millis() both rely on interrupts, they will not work while an ISR is running. delayMicroseconds(), which does not rely on interrupts, will work as expected.


此外, 應該習慣把 ISR 簡化, 不要比太多工作放在 ISR 中.  
嘗試在 ISR 中只設定一些變數, 再在主程式中檢測逐變數, 執行有關工作.
回复 支持 反对

使用道具 举报

发表于 2014-11-18 12:50:32 | 显示全部楼层
本帖最后由 i7456 于 2014-11-19 11:52 编辑
  1. int pin = 13;
  2. volatile int state = 0;
  3. long previousMillis = 0;         

  4. void setup()
  5. {
  6.   pinMode(pin, OUTPUT);
  7.   attachInterrupt(0, blink, FALLING);
  8. }

  9. void loop()
  10. {
  11.         previousMillis = millis();

  12.         if(!state) digitalWrite(pin, LOW);

  13.           while(state)
  14.           {
  15.                   digitalWrite(pin, HIGH);

  16.                 if((millis() - previousMillis) > 1000)
  17.                 state = 0;               
  18.           }

  19. }

  20. void blink()
  21. {
  22.   state = 1;
  23. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2014-11-18 21:45:34 | 显示全部楼层
中断服务程序一般很简短,只实现一个开关的功能,比如定义 volatile boolean pushed = false,中断里面就操作 pushed = !pushed,loop里面写 if(pushed){digitalWrite(LED,HIGH);delay(1000);else{digitalWrite(LED,LOW)}}
回复 支持 反对

使用道具 举报

发表于 2014-11-18 21:46:47 | 显示全部楼层
i7456 发表于 2014-11-18 12:50

你这个代码跑不了的,中断里面使用的变量必须使用volatile声明,不然会被优化掉
回复 支持 反对

使用道具 举报

发表于 2014-11-19 11:51:36 | 显示全部楼层
qptimus 发表于 2014-11-18 21:46
你这个代码跑不了的,中断里面使用的变量必须使用volatile声明,不然会被优化掉

谢谢提醒。
程序写完我没测试。
回复 支持 反对

使用道具 举报

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

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-9 01:49 , Processed in 0.048395 second(s), 20 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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