a_wesker 发表于 2015-4-18 21:30:26

求教~如何在中断函数中监控时间?

现在就是一个阀门条件触发开了之后要开10秒后关闭,所以即使阀门开启后遇到中断,也必须监控时间以便及时关闭。不需要很精确,精确到0.1秒就可以。但是中断了之后millis()不能用了。我现在只想了一个办法,就是从时钟模块读取时间,再计算出时间戳,可是好麻烦啊。请教各位大大有没有更好的实现方法?
{:soso_e110:}

darkorigin 发表于 2015-4-18 23:25:41

用个时钟模块 貌似也可以用中断的。
只是不知道单片机的中断是否也有优先级设置。

tsaiwn 发表于 2015-4-19 01:38:41

這精确到0.001秒
volatile int hasInt = 0;
volatile int moreInt = 0;
boolean doorIsOpen = false;
unsigned long doorOpenTime = 0;// 记住 阀门 被打开的时间
const unsigned int openLimit = 10 * 1000;// 10秒
your_ISR(中断程序){   // 中断 ?
   if(hasInt == 1){// 前次中断事情还没处理完
      ++moreInt;
      return;
   }
   hasInt = 1;// 标记中断刚发生
}
void setup( ) {
//...
}
void loop( ) {
   checkDoor( );
   //...
   if(该开阀门){
       开阀门;
       doorOpenTime = millis( ); // 记住开阀门时间
       doorIsOpen = true;
   } // if(
   //..
   if(hasInt) {
      processInt( );   // 触屏中断刚发生
      hasInt = moreInt = 0;// clear the Flag
   }
   //...
}
void processInt( ) {// 你触屏中断 !
   moreInt = 0;
   // 要 5秒 timeout 或 User 确定就退出
   // 把 5 秒切成 5000 个 ms; 或 2500次每次 delay(2); 或 1000次每次delay(5)
   for(int i=0; i< 5000; ++i) {// 可把 5000 改为 4998 可能比较接近 5 秒
       delay(1);// 1 ms
       checkDoor( );// 看看是否该关闭阀门
       if(moreInt !=0) {
          又发生了中断 !又点触屏??
          //.. 准备离开这循环
          return;    //up to you ?????
       }
       if(用户点了确定){
          //.. 做你要做的事
          return;
       } // if(
   } // for(// 注意这样总共会超过 5 秒一点点 !
   Serial.println("Time out");
   //.. 做 time out 要做的事
} // processInt(
void checkDoor( ) {   // 检查看看是否该关闭阀门
   if( doorIsOpen == false ) return;
   if( millis( ) - doorOpenTime < openLimit) return; // 时间还没到
   doorIsOpen = false;
   做关闭阀门;
}
////////////End

stpanzj 发表于 2015-4-19 12:23:37

一般情况下,中断服务程序都很短,应该<0.1s而且要大大小于的。所以只要在关阀门时记住当时的时间,在主程序中进行判断就可以及时关闭阀门的。或者在主程序中启动一个定时中断启动关闭动作更精确些。
页: [1]
查看完整版本: 求教~如何在中断函数中监控时间?