万马奔腾 发表于 2013-5-12 10:59:32

利用内部时间中断函数如何实现多次不同间隔时间的中断啊?

如程序所示:想实现第多次不同间隔时间让LED灯亮灭一次// led灯接UNO的13管脚
#include   <MsTimer2.h>   //定时器库的 头文件
int i=500;                   //定义初始值,500MS执行中断
int flag=1;                  //记录中断的次数

void flash()                //中断处理函数,13#LED灯亮500MS后灭
{                        
digitalWrite(13, HIGH);
delay(500);            //这里用delay函数是否影响其他程序
digitalWrite(13, LOW);
switch (flag) {
case 1:                //第一次中断后设置下一次中断的时间
    {i=i+1000;            //下次中断的时间设置1.5秒
   flag+=1;
   break;}
case 2 :               //第二次中断后设置下一次中断的时间
{ i=i+2500;          //下次中断的时间设置4秒
   flag+=1;            
   break;}
case 3:            //第三次中断后设置下一次中断的时间
    { i=i+ 4500;            //下次中断的时间设置8.5秒
   flag+=1;
   break;}
}
}
void setup()
{
pinMode(13, OUTPUT);
MsTimer2::set(i, flash);   // 中断设置函数,
MsTimer2::start();         //开始计时
}

void loop()
{

}

万马奔腾 发表于 2013-5-12 11:13:35

// led灯接UNO的13管脚
#include   <MsTimer2.h>   //定时器库的 头文件
int i=500;                   //定义初始值,500MS执行中断
int flag=1;                  //记录中断的次数

void flash()                //中断处理函数,13#LED灯亮500MS后灭
{                        
digitalWrite(13, HIGH);
delay(500);            //这里用delay函数是否影响其他程序
digitalWrite(13, LOW);

}
void setup()
{
pinMode(13, OUTPUT);

}

void loop()
{
MsTimer2::set(i, flash);   // 中断设置函数,
MsTimer2::start();         //开始计时
switch (flag) {
case 1:                //第一次中断后设置下一次中断的时间
    {i=i+1000;            //下次中断的时间设置1.5秒
   flag+=1;
   break;}
case 2 :               //第二次中断后设置下一次中断的时间
    { i=i+2500;            //下次中断的时间设置4秒
   flag+=1;            
   break;}
case 3:                //第三次中断后设置下一次中断的时间
    { i=i+ 4500;            //下次中断的时间设置8.5秒
   flag=1;
   i=500;
   break;}
}

}
改成以上代码之后,LED没有反应;
有几个问题:1
1.定时中断函数不能放入LOOP循环里吗?
2.能够修改中断函数的时间;
3.中断函数能否用delay();

学长 发表于 2013-5-12 12:07:36

本帖最后由 学长 于 2013-5-12 12:34 编辑

我最近也是接触定时器.. 你用的是 mstime2
我用的是 TimerOne
不过, 大致上要把握2个重点,
1.中断 interupt 的动作是停止目前 CPU 所执行的程序
然後进行中断指定的处理指定.. 一般来说,中断之後会指定一个中断处理函数。
2. ATmega 168/328 并非真实的多执行绪

所以解答就出来了
1.中断函数如果放入 loop 里面, 那函数就不只有中断时执行。
2.中断时间可以修改, 我比较习惯的方式是, 把 timer 当是计时器,每 Tick 多少时间,
   再由 Tick 来还原时间,并执行相应的函数。
3.應該能使用 但手冊上 說中斷時 delay 時間不變

学长 发表于 2013-5-12 12:13:10

BTW
你更改过後的程序逻辑就不对了.. .
Setup 跟 loop 还没分清楚吧?

zjyylj 发表于 2013-6-1 15:30:25

本帖最后由 zjyylj 于 2013-6-2 20:37 编辑

中断函数发生时,delay()和millis()的数值将不会继续变化。
这儿有个第三方的Timer库

你可以试试看,我正在学习。

zjyylj 发表于 2013-6-1 16:56:19

本帖最后由 zjyylj 于 2013-6-1 17:00 编辑

首先有些概念上的错误:
【1】MsTimer2::set(unsigned long ms, void (*f)())这个函数第一个参数的类型是unsigned long,不是int。
【2】setup()中的函数只执行一遍,也就是MsTimer2::set(i, flash);执行完之后,虽然 i 改变了,但是定时器的间隔并没有变化。
【3】在中断函数发生时,delay的值不会变化。
我的板子是Mega2560,用不了MsTimer2,用FlexiTimer2代替,按你的要求写了个类似的程序,测试通过。/* 用FlexiTimer2实现不同时间间隔的中断
   要点:在中断函数的子块中要暂停原来的中断,开始新的中断
         这样新的时间间隔才能生效
         如果只是执行一个LED的通断,
         最好不要使用delay(),
         在需要控制的时候再调用函数,
         其他时间释放MCU。
   功能:13脚的LED点亮2秒,熄灭0.5秒。
         在case中添加更多情况可实现更多功能。
    ******* Made by zjyylj *********
*/

#include   <FlexiTimer2.h>   //定时器库的 头文件
unsigned long i=1000;            //定义初始值,1000MS执行中断
int flag=1;                  //中断index号

void flash()                //中断处理函数
{                        
Serial.println("main");

switch (flag) {
case 1:                //第一次中断后设置下一次中断的时间
    {
      FlexiTimer2::stop;
      digitalWrite(13, HIGH);
      i=i+1000;            //下次中断的时间设置2秒
      flag=2;
      Serial.println("case1");
      FlexiTimer2::set(i, flash);
      FlexiTimer2::start();
      break;
    }
case 2 :               //第二次中断后设置下一次中断的时间
    {
      FlexiTimer2::stop;
      digitalWrite(13, LOW);
      i=500;            //下次中断的时间设置0.5秒
      flag=1;
      Serial.println("case2");
      FlexiTimer2::set(i, flash);
      FlexiTimer2::start();
      break;
    }
}
}
void setup()
{
Serial.begin(9600);
pinMode(13, OUTPUT);
FlexiTimer2::set(i, flash);   // 中断设置函数,
FlexiTimer2::start();         //开始计时
}

void loop()
{
}
这个同时只能启用一个中断,过段时间我写个用第三方Timer库做的多种间隔中断同时启用。

zjyylj 发表于 2013-6-1 18:04:38

本帖最后由 zjyylj 于 2013-6-2 20:37 编辑

第三方Timer库已经翻译,详见
wiki链接

jike程铭 发表于 2014-4-13 10:31:43

zjyylj 发表于 2013-6-1 16:56 static/image/common/back.gif
首先有些概念上的错误:
【1】MsTimer2::set(unsigned long ms, void (*f)())这个函数第一个参数的类型是u ...

好像你这也只循环一次吧进入setup中,执行初始化,执行Flash函数,switch中break 直接跳出整个。loop中
中中断函数和计时函数吧

dbwing520 发表于 2014-5-13 04:57:08

zjyylj 发表于 2013-6-1 16:56 static/image/common/back.gif
首先有些概念上的错误:
【1】MsTimer2::set(unsigned long ms, void (*f)())这个函数第一个参数的类型是u ...


FlexiTimer2怎么用啊

看wiki里有 Timer - 利用millis()函数来模拟多线程 的用法

另外求一个 Timer库

inovar 发表于 2014-6-21 11:25:25

初学Arduino定时器,thank you!

pumpitup 发表于 2016-5-28 12:00:14

存了
有时间看看
页: [1]
查看完整版本: 利用内部时间中断函数如何实现多次不同间隔时间的中断啊?