精华内容
下载资源
问答
  • Arduino 外部中断

    2021-05-02 22:04:09
    停止再在执行的内容去执行中断函数中的内容 Arduino型号 int0 int1 int2 int3 int4 int5 UNO 2 3 – – – – MEGA 2 3 21 20 19 18 Leonardo 3 2 0 1 – – 中断触发模式 模式名称 说明 LOW ...

    外部中断

    外部中断是由控制器设备发起的中断请求。停止再在执行的内容去执行中断函数中的内容
    Arduino型号int0int1int2int3int4int5
    UNO23
    MEGA2321201918
    Leonardo3201
    中断触发模式
    模式名称说明
    LOW低电平触发
    CHANGE电平变化触发(即高变低,低变高)
    RISING上升沿触发,即低变高
    FALLING下降沿触发,高变低

    大多数Arduino支持上述四种触发方式

    使用中断函数


    void setup(){
    	attachInterrupt(中断编号, 中断函数名, 中断触发模式);
    }
    // 例如 attachInterrupt(0,blink,LOW); UNO: 数字引脚2,低电平触发
    // detachInterrupt(interrupt) 禁用外部中断
    //interrupt 为禁用中断编号
    
    注意
    attachInterrupt() 和 detachInterrupt()两个函数
    中断函数不能带有参数
    中断函数要在setup() 函数和 loop() 函数外面();
    展开全文
  • 由于arduino官方提供的红外遥控...这里使用外部中断加定时器1来实现红外遥控nec协议的解码。 板子:arduino uno 中断引脚:2 定时器:1 实现功能:可以接收nec协议的红外编码,并且可以连续接收(如果遥控器支持的话)
  • 通过生活中一个简单的例子来说明中断。当你正在家中看书时,突然电话铃响了,你停止看书,去接电话,和来电话的人进行交谈,通话结束后回来继续从刚才...Arduino 中的中断可以分为两类:外部中断和定时中断。 外部...

    通过生活中一个简单的例子来说明中断。当你正在家中看书时,突然电话铃响了,你停止看书,去接电话,和来电话的人进行交谈,通话结束后回来继续从刚才停止的位置看你的书。这就是生活中的“中断”的现象,就是正常的工作过程被外部的事件打断了。程序中的中断是指在主程序执行过程中被中断,执行中断服务程序,待中断服务程序执行完之后继续接着执行主程序。

    Arduino 中的中断可以分为两类:外部中断和定时中断。
    外部中断: 一般是指由外设发出的中断请求,即中断源在外部如:键盘中断、打印机中断等。外部中断需要外部中断源发出中断请求才能发中断。有关外部中断的详细用法见《Arduino 外部中断的使用》一文。
    定时中断:主程序在运行的过程中过一段时间就进行一次中断服务程序,不需要中断源的中断请求触发,而是自动进行。

    我们可以根据实际情况的不同来确定使用什么样的中断。
    中断的函数:
    首先介绍关中断和开中断即Interrupt()和noInterrupt()函数,用法如下。

     

    {

    可以被中断的代码

    Interrupt()

    不可以被中断的代码

    noInterrupt()

    可以被中断的代码

    }

    定时中断

    Arduino已经为我们写好了定时中断的库函数了,我们可以直接直接使用,这对于对底层了解较少的同学来说真是一个好消息。常用的库有FlexiTimer2.h和MsTimer2.h,这两个库的用法是大同小异的。下面对其中的几个常用的函数进行详细的介绍。这两个库你可以很轻松的从网上下载。
    1.void set(unsigned long ms, void (*f)())
    这个函数设置定时中断的时间间隔和调用的中断服务程序。ms表示的是定时时间的间隔长度,单位是ms,void(*f)()表示被调用中断服务程序,只写函数名字就可以了。

    2.void start()
    开启定时中断

    3.void stop()
    关闭定时中断

    注意:以上三个函数都是在MsTimer2的作用于中进行的,在使用时都要加上作用域,如:MsTimer2::start();可以通过下面这个例子来详细的了解一下定时中断。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    //定时器库的 头文件

    #include <MsTimer2.h>

    //中断处理函数,改变灯的状态

    void flash()

    {                      

       static boolean output = HIGH;

       digitalWrite(13, output);

       output = !output;

    }

    void setup()

    {

       pinMode(13, OUTPUT);

       // 中断设置函数,每 500ms 进入一次中断

       MsTimer2::set(500, flash);

       //开始计时

       MsTimer2::start();

    }

       

    void loop(){

     

    }


     

    文章目录


    ARDUINO TIMER AND INTERRUPT TUTORIAL:https://oscarliang.com/arduino-timer-and-interrupt-tutorial/

     

    3. 使用 MsTimer2 库定时做多件事(教程)(定时器timer2的使用)

    转载:使用 MsTimer2 库定时做多件事(教程)(定时器timer2的使用)
    https: //www.arduino.cn/thread-12435-1-1.html
    (出处: Arduino中文社区)

    3.1 相关资料

    1. 可以自己用 millis( ) 或 micros( ) 检查时间以决定是否该做事了:
      http: //arduino.cc/en/Reference/Millis
      http: //arduino.cc/en/Reference/Micros

    2. 可以看看我写的这篇"不使用 Timer 库要定时做某事或做两三件事(教程)定时器相关":
      http: //www.arduino.cn/thread-12408-1-2.html

    3. 也可以使用 Timer 库或 SimpleTimer 库或类似的库做设定:
      http: //playground.arduino.cc/Code/Timer
      http: //playground.arduino.cc/Code/SimpleTimer
      不过 Timer 库和 SimpleTimer 库也都是使用 millis( ), 很容易被 loop( ) 内其他事搞成"很不准"!

    4. 你当然可以自己控制内部定时器 timer0, timer1, timer2 写ISR(), 可参考:
      http: //www.hobbytronics.co.uk/arduino-timer-interrupts
      http: //www.engblaze.com/we-interrupt-this-program-to-bring-you-a-tutorial-on-arduino-interrupts/
      http: //www.instructables.com/id/Arduino-Timer-Interrupts/step1/Prescalers-and-the-Compare-Match-Register/
      http: //www.instructables.com/id/Arduino-Timer-Interrupts/step2/Structuring-Timer-Interrupts/

    5. 自己控制内部定时器 ,那相对比较难且很容易出错! 所以,想要比较精准定时做某件事, 最简单的就是使用硬件中断的 MsTimer2 库
      http: //playground.arduino.cc/Main/MsTimer2
      (注意这库精准度只有以 milli second 为单位)

    3.2 MsTimer2 库简单又好用,

    3.2.1 库地址:

    https://www.pjrc.com/teensy/td_libs_MsTimer2.html
    MsTimer2, by Javier Valencia, lets you periodically run a function, by a configurable number of milliseconds.

    FlexiTimer2 is version of MsTimer2 by Wim Leers, which makes the interval resolution configurable, rather than being fixed at 1 millisecond steps
    Javier Valencia的MsTimer2允许您定期运行一个函数,可配置为毫秒数。 FlexiTimer2是在MsTimer2版本基础上修改的,它可配置间隔分辨率,而不是固定在1毫秒级

    Download: [Included with the Teensyduino Installer](https: //www.pjrc.com/teensy/td_download.html)
    Latest MsTimer2 on [Github](https: //github.com/PaulStoffregen/MsTimer2)
    Latest FlexiTimer2 on [Github](https: //github.com/PaulStoffregen/FlexiTimer2)

    3.2.2 MsTimer2 库函数介绍

    • 设定时间与要执行的 function
      MsTimer2: : set( some_ms, your_function);
    • 启动中断
      MsTimer2: : start();
    • 必要时可停止中断(当然随时可以再重新启动)
      MsTimer2: : stop();
      先来看一个简单范例: (改自原本范例)#

    3.2.3 程序范例

    #include <MsTimer2.h>
    const int INTERVAL = 500;   // 0.5 秒 = 500ms
    void ggyy( ) {
       static int gy = 0;
       gy = 1- gy;  // toggle 0,  1
       digitalWrite(13,  gy);  // pin 13 LED
    }
    void setup( ) {
      pinMode(13,  OUTPUT);
      MsTimer2::set(INTERVAL,  ggyy); // INTERVAL ms 
      MsTimer2::start( );
    }
    void loop( ) {
      delay(6123);  // 故意
      MsTimer2: : stop( );
      delay(3388);
      MsTimer2: : start( );
    }
    

    程序说明

    1. 这范例让 pin 13 的 LED 灯闪烁大约6秒, 然后停大约 3.4秒, 之后又闪烁大约6秒, 然后停大约 3.4秒, … 亮灭间隔是 0.5 秒(500 ms) !
    2. 你会发现: 用 MsTimer2 只能设定一件要定时做的事 !
      查看 MsTimer2 库的 source code 你会发现,重复使用 MsTimer2: : set( ) 只有最后一次有效,因为每次使用 MsTimer2: : set( ) 会盖掉前一次的设定 ! !
    3. 那如果我有两件事想要定时做呢? 其实也很简单:
      就是把原先定时做的事改为负责计时,并判定是否要做其他事即可!
      以下是要定时做两件事的范例:
      (A) 每 250 ms 做一次 myJobOne : 闪烁 LED on pin 13
      (B) 每 250 ms 做一次 myJobTwo : 闪烁 LED on pin 8
    #include <MsTimer2.h>
    const int intA = 250;  //每 250 ms 做一次 myJobOne
    const int intB = 250;  // 每 250 ms 做一次 myJobTwo
    int led2 = 8;  // pin 8
    const int INTERVAL = 1;   // 0.001 秒 = 1ms
    void ggyy( ) {
       static unsigned int gy = 0;
       ++gy;
       if( gy % intA == 0) myJobOne( );   // gy 除以 intA 的余数是 0
       if( gy % intB == 0) myJobTwo( );
    }
    void setup( ) {
      pinMode(13,  OUTPUT);
      pinMode(led2,  OUTPUT);
      MsTimer2::set(INTERVAL,  ggyy); // INTERVAL ms 
      MsTimer2::start( );
    }
    void loop( ) {
      delay(6123);  // 故意
      MsTimer2::stop( );  
      delay(3388);  
      MsTimer2::start( );
    }
    void myJobOne( ) {
       static int gy = 0;
       gy = 1- gy;  // toggle 0,  1
       digitalWrite(13,  gy);  // pin 13 LED
    }
    void myJobTwo( ) {
       static int gy = 1; // 故意与 myJobOne 内gy不同 ! 
       gy = 1- gy;  // toggle 0,  1
       digitalWrite(led2,  gy);  // pin 8 LED
    }
    

    3.3 MsTimer2库注意事项

    1. 请注意, 如果你使用了 MsTimer2 库, 则 pin11 和 pin3 就不能再用做 PWM 输出了! 因为该 pin3 和 pin11 的 PWM 是靠 timer2 帮忙的! (tone( ) 也是)
    2. 注意 Servo.h 库与 TimerOne 都是使用内部定时器 timer1 会影响pin 9, pin 10 的 PWM
    3. **tone() function ** 使用 timer2 定时器; 若使用 Tone 库的 Tone 对象(Tone 变量)也是优先使用 timer2 定时器,若用两个 Tone 变量则 timer1 也会被用掉, 用三个 Tone 则连控制 millis( )的 timer0 也会被用掉 ! ! !
      别忘了, timer0 负责帮忙控制 pin 5 和 pin 6 的 PWM 输出 ! ! !
      只要不去改变 timer 的 Prescaler就不会影响其控制的 PWM pin, 但MsTimer2 库与 tone( )都会改变 Prescaler ! !

    3.4 疑问解答

    问答1

    Q: 这范例显然每0.25秒都 “先” 做 myJobOne, 然后再做 myJobTwo, 并没有 “同时” 做啊?
    A: 不然还能怎样 ?
    Arduino 的 CPU 只有一个, 又不是多核心(multi core), 怎可能真的"同时"做呢 ? 不过 Arduino 在 16MHz 频率之下每个C语言的指令大约0.7到 3 micro seconds,
    如果做了二十句 C语言指令也才大约 0.05 ms (milli second),
    进入 ISR( )与离开 ISR( )总计大约要 3 micro seconds,
    进入 function 与离开 function 也大约3 micro seconds,
    所以, 两个工作前后差不到 0.1 个千分之一秒 ( 0.1 ms), 感觉还是 “同时” 做啦 !
    如果你认为应该优先处理 myJobTwo, 那就把该两句检查 gy 的 if 前后对调即可 !

    问答2

    Q: 例中 intA 和 intB 可不可以设不一样呢?
    A: 当然可以啊 !
    你可以把 intB 改为 500 或 1000 自己测试看看 !

    问答3

    Q: 那如果要设定为定时做三件事呢?
    ㄟ … 阿这个看完上面例子你应该就会了啊 !
    只要多用个类似 intA 与 intB 的 intC 就可以仿照写出了!
    好啦, 为了让初学新手更清楚如何"仿照"写出多一件事要定时做,
    以下再改一下上述范例给新手参考,
    这次在第三个定时的变量我故意命名 int38 以免有人误以为一定要叫做 intC !

    /// 利用 MsTimer2 定时做三件事
    #include <MsTimer2.h>
    const int intA = 250;  //每 250 ms 做一次 myJobOne
    const int intB = 250;  // 每 250 ms 做一次 myJobTwo
    int int38 = 1000; // 每 1 秒做一次 myJob666; 没规定说必须用 const : -)
    int led2 = 8;  // pin 8
    int led3 = 7;  // pin 7
    const int INTERVAL = 1;   // 0.001 秒 = 1ms
    void ggyy( ) {
       static unsigned int gy = 0;
       ++gy;
       if( gy % intA == 0) myJobOne( );
       if( gy % intB == 0) myJobTwo( );
       if( gy % int38 == 0) myJob666( );
    }
    void setup( ) {
      pinMode(13,  OUTPUT);
      pinMode(led2,  OUTPUT);  pinMode(led3,  OUTPUT);
      MsTimer2::set(INTERVAL,  ggyy); // INTERVAL ms 
      MsTimer2::start( );
    }
    void loop( ) {
      // 这次 loop( ) 内故意甚么都不写
    }
    void myJobOne( ) {
       static int gy = 0;
       gy = 1- gy;  // toggle 0,  1
       digitalWrite(13,  gy);  // pin 13 LED
    }
    void myJobTwo( ) {
       static int gy = 1; // 故意与 myJobOne 内gy不同 ! 
       gy = 1- gy;  // toggle 0,  1
       digitalWrite(led2,  gy);  // pin 8 LED
    }
    void myJob666( ) {
       static int gy = 0;
       gy = 1- gy;  // toggle 0,  1
       digitalWrite(led3,  gy);  // pin 7 LED
    }
    

    问答4

    Q: 可不可以定时做四件事或更多呢?
    A: 用脚头乌(膝盖)想也知道当然可以, 不过这时你可能想用 Array 来记住
    所有的设定时间与对应的 function, 以免 code 太长太丑看了不爽 : -)

    问答5

    Q: 还有哪些要注意或限制的呢?
    A:

    • 因为用 MsTimer2 库是在中断时做事, 每件事都要越快做完越好,
    • 还有, 这时中断在被禁止状态(interrupt is disable), 所以, 不要做会用到中断的事, 例如要避免做类似 Serial.print 的事 !
    • 本范例是每 1 ms 执行一次 ggyy( ); 所以, 你所有利用这来定时做的 myJob* 总运行时间要小于 1ms, 不然万一都要"几乎同时做"会来不及 !
    • 最后再提醒一下, 因为 MsTimer2 库会改变内部 timer2 定时器的 Prescaler, 也因为这样, 由 timer2 定时器帮忙做 PWM 的 pin 11 与 pin 3 就不能用 analogWrite 做 PWM 输出了 !

    问答6

    Q: 可是我需要定时做 Serial.print 怎办?
    A: 那你应该用个 volatile 变量的 flag, 在 myJob* 内设定该 flag,
    然后在 loop( ) 内检查该 flag 以决定是否要使用 Serial.print 打印资料!
    注意, 这时在 loop( ) 内也必须尽量不要使用 delay( ) 以免太慢才
    检查到 flag 的变化!
    我这两个范例故意在 loop( ) 内使用 delay( ) 只是要示范说
    可以随时把 MsTimer2 的定时功能关闭,然后可以随时重新启动定时做事!

    问答7

    Q: 我用 MsTimer2 库定时 1000 做一个时钟, 可是好像时钟不太准确 !

    A: 那如果你是设定 1000 想要定时 1000ms 做一次把秒数加 1, 像这:
    MsTimer2::set( 1000, ggyy); // 1000 ms
    MsTimer2: : start( );
    然后以为 ggyy( ) 是 每 1 秒做一次, 那就有点错了 !
    Why ??
    因为 使用内部 timer2, timer2 的计数器 counter 与 timer0 的都只有 8 bit,
    受限于 8-bit 配合 Prescaler 64, 无法做到真的刚好 1ms, 它所谓的 1ms 其实是 1.024ms;
    这在大部分的应用不会有问题, 但如果你要拿来做时钟, 就必须学 Arduino 系统在计算 millis( ) 的做法做修正:
    在由 timer0 每 1.024 ms 发动的 ISR( ) 内, 它除了每次中断把 millis 加 1, 另外把一个偷用的变量 gg += 3; 就是每次中断 +3; 然后检查是否 >= 125, 如下:

               if( gg >= 125) {
                    gg-= 125;
                    ++ millis;
               }
    
     这个动作使得中断每过大约 41次或42次会偷偷调整 millis,  以便弥补每次少算的 0.024ms;
    
    •  

    所以, 如果你要拿 MsTimer2 库来写时钟, 请不要设 1000, 改为设 1 代表 1.024 ms 会产生一次中断,
    然后, 自己学 millis( ) 函数的做法:

    void ggyy( ) {
          static unsigned int  ms = 0;
          static unsigned char gg = 0;
          ++ms;  gg+=3;
          if(gg >= 125) { gg-=125;  ++ms;}
          if( ms < 1000) return;
          ms -= 1000;
         // 把秒 + 1
         检查秒是否 >= 60 ...
         ...
    } // ggyy(
    

    *更多关于 Arduino 内部定时器与中断的说明可以参考:
    http: //www.uchobby.com/index.php/2007/11/24/arduino-interrupts/
    http: //www.engblaze.com/microcontroller-tutorial-avr-and-arduino-timer-interrupts/
    http: //gammon.com.au/interrupts
    http: //www.avrbeginners.net/architecture/timers/timers.html
    http: //sphinx.mythic-beasts.com/~markt/ATmega-timers.html
    http: //maxembedded.com/2011/07/avr-timers-ctc-mode/

    6. 自己控制 timer2 定时器定时做多件事(教程, 设定timer2 定时器)

    自己控制 timer2 定时器定时做多件事(教程, 设定timer2 定时器)
    https: //www.arduino.cn/thread-12448-1-1.html
    (出处: Arduino中文社区)

    昨天跟大家分享了自己控制 timer1 定时器做多件事:
    http: //www.arduino.cn/thread-12445-1-1.html
    即使你看不太懂程序内的许多句子,
    仍然可以稍微修改就能用来"定时"做你要做的事 {: soso_e100: }
    但是,如果你用了 Servo.h 库就不能自己控制 timer1 定时器了 {: soso_e115: }
    所以,我跟大家再分享如何改为控制 timer2 定时器做多件事。

    以下这范例只是把我上次写的控制 timer1 定时器做两件事的程序拿来
    
    •  

    改为控制 timer2 定时器做两件事:
    仍然是以不同的频率闪烁 pin 13 LED 与 pin 8 LED;
    提醒别忘了 pin 8 的 LED 要串接大约 220 奥姆的电阻,
    不过万一没有电阻, 那就多串接一个 LED 应该也可避免 LED 灯烧坏

    使用 timer2 与 timer1 定时器做定时原理完全一样,
    主要差别是 timer1 是 16bits, 但 timer2 (和 timer0) 只有 8 bits,
    意思是 TCNT2, OCR2A, OCR2B 都是 8位, 其内容只能是 0 到 255 (十六进制 0xFF);
    所以 myTOP 改用8位的 uint8_t, 也就是 unsigned char,
    要注意的是, 既然程序内 myTOP 就是要给 timer2 定时器的计数缓存器(register) OCR2A 使用,
    因此 myTOP 的最大值就只能到 255; 这范例中我们使用 24 刚好没问题
    设定 myTOP 为 24 的理由在程序内的这段批注(注释):
    /// For Prescaler == 64
    /// 1 秒 / (16 000 000 / 64) = 1/250000 = 0.000004 sec / per cycle
    /// 0.1 sec / 0.000004 sec -1 = 25000 -1 = 24999
    /// 0.0001 sec / 0.000004 sec -1 = 25 -1 = 24
    ///需要减去 1 是因为 CTC mode 在比到 TCNT2 == OCR2A 时要重设 TCNT2 并发动中断需要 1 个 cycle (tick)
    请注意这里是假设你的 Arduino 是使用 16MHz 的频率。
    还有, 虽然同样是设定 Prescaler 为 64,在 timer2 与 timer1 的设定也不太一样。

    我们仍用 CTC mode(Clear Timer on Compare),
    可是设定 timer2 与设定 timer1 为 CTC mode 方法不太一样,
    所以如果你只是复制之前的 timer1 版本来乱改不看手册是不通的 !
    由 datasheet 知道 timer2 的 mode 由 WGM22, WGM21, WGM20 这 3 bit决定,
    这三位是 010 表示用 mode 2 的 CTC 且 TOP 在 OCR2A;
    所以, 我们要把 WGM21 设定为 1,
    但是,
    要注意 WGM22 在 TCCR2B, 而 WGM21 与 WGM20 在 TCCR2A;
    是 0 的位就不管它, 所以要写 TCCR2A = ( 1 << WGM21 ); 以便把 WGM21 设定为 1;
    (程序中我故意定义了一个 Macro 宏 bbs(x) 来帮忙做 ( 1 << x ) 这件事)
    请参考 ATmega328 datasheet 关于 Timer2/Counter2 (See p.158-162):
    http: //www.atmel.com/Images/doc8161.pdf

    kittenblock中小学创客名师推荐的图形化编程软件

    // 控制 LED on pin 13亮灭,  每秒闪烁 2 次:  亮 0.25 秒灭 0.25 秒 ...
    // LED on pin 8 每秒闪烁 1 次:  亮 0.5 秒灭 0.5 秒 ...
    #define bbs(x)  (1<<x)
    const int intA = 2500;   // 2500 * 0.1 ms = 250ms
    const int intB = 5000;   // 5000 * 0.1 ms = 500ms = 0.5秒
    // Prescaler 用 64
    volatile int ggyy = 1;  // 使用这当 Flag 给  ISR 使用 ! 
    int ledPin =13;
    int led8 = 8;  // pin 8
    /// For Prescaler == 64
    ///  1 秒 / (16 000 000 / 64) = 1/250000 =  0.000004 sec / per cycle
    /// 0.1 sec / 0.000004 sec -1 = 25000 -1 = 24999
    /// 0.0001 sec / 0.000004 sec -1 = 25 -1 = 24
    const uint8_t myTOP = 24;  // 0.0001 sec when Prescaler == 64
    / Interrupt Service Routine for TIMER1 CTC on OCR1A as TOP
    /// 注意以下名称是有意义的,  不可乱改 ! 
    ISR(TIMER2_COMPA_vect)
    {
       static unsigned int aaa = 0;
       static unsigned int bbb = 0;
       ++aaa; bbb++;
       if(aaa == intA){
          aaa=0; myJobOne( );
       }
       if(bbb == intB){
          bbb=0; myJobTwo( );
       }
    }
    void setup( ) {
      pinMode(ledPin,  OUTPUT);
      pinMode(led8,  OUTPUT); digitalWrite(led8,  1); // 故意
      digitalWrite(ledPin,  LOW); // turn Off the LED
      setMyTimer2( );
    }
    void loop() {
      //... 做其他事
      // if( ggyy == 1) ...
    }
    void myJobOne( ) {
      digitalWrite(ledPin,  ggyy);  // ggyy 是 0 或 1
      ggyy = 1 - ggyy; //  给下次进入 用
    }
    void myJobTwo( ) {
      digitalWrite(led8,  !  digitalRead(led8));  // Toggle led8
    }
    
    void setMyTimer2( ){
      cli();  // 禁止中断
      TCCR2A = bbs(WGM21);  // CTC mode 2; Clear Timer on Compare,  see p.158-162
      TCCR2B = bbs(CS22);  // Prescaler == 64; see p.162 in datasheet 
      / 注意 WGM22 在 TCCR2B,  但 WGM21 与 WGM20 在 TCCR2A; 
      / mode 由 WGM22,  WGM21,  WGM20 决定 (see datasheet p.158-162)
      OCR2A = myTOP;  // TOP count for CTC,  与 prescaler 有关
      TCNT2=0;  // counter 归零 
      TIMSK2 |= bbs(OCIE2A);  // enable CTC for TIMER2_COMPA_vect
      sei();  // 允许中断
    }
    

    /// ATmega328 datasheet http: //www.atmel.com/Images/doc8161.pdf (p.158-162)
    //

    有了上面这精准度 0.1 ms 做中断的范例(使用 timer2 定时器),
    即使你使用 Servo.h 库(会用到 timer1 定时器),
    你仍然可以"定时"做某些事, 不会因 loop( ) { } 内有 delay( )影响到,
    且应该也很容易修改为定时做三件或更多事。
    注意这范例也是用两个不同的变数(变量 aaa, bbb)分别计数并检查
    是否到了该做 myJobOne( ) 与 myJobTwo( ) 的时机 !
    所以要多设定一件事, 就仿照多弄个变量例如 ccc, 写个新工作的 function,
    然后复制检查的 if 区块并稍微改一下即可

    Q: 还有哪些要注意的吗 ?
    A: 提醒 timer2 控制 pin 11 和 pin 3 的 PWM 输出,
    所以改变 timer2 的 Prescaler 就不能再对 pin 3 和 pin 11 做 analogWrite( )了,
    还有, Arduino 自带的 tone( ) 函数也会改变 timer2 的 Prescaler:
    http: //arduino.cc/en/reference/tone
    当然还要注意有些第三方的库也可能会使用 timer2 定时器,
    其他注意事项请看可看我之前写的
    “使用 MsTimer2 库” 的分享内容:
    http: //www.arduino.cn/thread-12435-1-1.html

    以及关于 “使用 TimerOne 库” 的分享:
    http: //www.arduino.cn/thread-12441-1-1.html

    更多关于中断(interrupt)的详细说明可以参考:
    http: //gammon.com.au/interrupts
    http: //www.uchobby.com/index.php/2007/11/24/arduino-interrupts/
    http: //www.engblaze.com/microcontroller-tutorial-avr-and-arduino-timer-interrupts
    http: //www.avrbeginners.net/architecture/timers/timers.html
    http: //letsmakerobots.com/node/28278
    http: //playground.arduino.cc/Main/MsTimer2

    还有以下这三篇也很有用:
    http: //sphinx.mythic-beasts.com/~markt/ATmega-timers.html
    http: //maxembedded.com/2011/07/avr-timers-ctc-mode/
    http: //arduino.cc/en/Tutorial/SecretsOfArduinoPWM

    展开全文
  • 外部中断在不同的Arduino型号上位置也不同,只有外部中断发生在以下端口,Arduino才能捕获到,以下例举了常见的几种型号的外部中断引脚标号。 型号 int.0 int.1 int.2 int.3 int.4 int.5 UNO\...

    外部中断在不同的Arduino型号上位置也不同,只有外部中断发生在以下端口,Arduino才能捕获到,以下例举了常见的几种型号的外部中断引脚标号。

    型号int.0int.1int.2int.3int.4int.5
    UNO\Ethernet23
    Mega25602321201918
    Leonardo3201
    Due 所有IO口均可

    例程

    外部中断的使用也是非常简单的,下面我们来看一个官方提供的例程。

    int pin = 13;
    volatile int state = LOW;
      
    void setup()
    {
      pinMode(pin, OUTPUT);
      attachInterrupt(0, blink, CHANGE);//当int.0电平改变时,触发中断函数blink
    }
      
    void loop()
    {
      digitalWrite(pin, state);
    }
      
    void blink()//中断函数
    {
      state = !state;
    }

    展开全文
  • 2,ISR,中断处理函数的名称 3,触发中断的引脚状态变化 LOW 引脚低电平触发中断 CHANGE 引脚电平变化触发中断RISING 引脚电平由低到高触发中断 FALLING 引脚电平由高到低触发中断 HIGH 引脚低高平触发中断(Ard

    使用attachInterrupt函数

    函数参数

    1,digitalPinToInterrupt(pin)   使用的中断,传入引脚号

    2,ISR,中断处理函数的名称

    3,触发中断的引脚状态变化

    • LOW 引脚低电平触发中断
    • CHANGE 引脚电平变化触发中断
    • RISING 引脚电平由低到高触发中断
    • FALLING 引脚电平由高到低触发中断
    • HIGH 引脚低高平触发中断(Arduino Due 板子才有)

    各板子的外部中断引脚号

    外部中断引脚号

    板子型号int.0int.1int.2int.3int.4int.5
    Uno, Ethernet23    
    Mega25602321201918
    32u4 based (e.g Leonardo, Micro)32017 

     Arduino Due所有数字引脚,ArduinoZero所有数字引脚除了引脚4

    示例程序如下


    int pin = 13;
    volatile int state = LOW;

    void setup(){
        pinMode(pin,OUTPUT);
        attachInterrupt(digitalPinToInterrupt(pin), blink,CHANGE);
    }

    void loop(){
        digitalWrite(pin, state);
    }

    void blink(){
        state = !state;
    }



    
    
    展开全文
  • Arduino外部中断

    千次阅读 2013-02-24 02:16:50
    1.什么是中断?  试想一下,你正在家里吃饭,这时传来了敲门声,虽然你巨饿,虽然面前全是山珍海味,但此时你不得不去开门,同时不得不放停下生命中最重要的事情——吃饭。打开门后,你发现只是一个查水表的,你...
  • Arduino 定时器中断 外部中断

    万次阅读 多人点赞 2019-04-09 17:29:31
    但如果此时发生了某一件事件B请求CPU迅速去处理(中断发生),CPU暂时中断当前的工作,转去处理事件B(中断响应和中断服务),待CPU将事件B处理完毕后,再回到原来被中断的地方继续执行程序(中断返回),这一过程成...
  • 各种Arduino外部中断程序

    万次阅读 2017-02-12 14:57:08
    一、中断(Interrupt)的基本概念 中断(Interrupt)是计算机的一个重要概念,现代计算机普遍采用中断技术。 什么是中断呢? CPU执行时原本是按程序指令一条一条向下顺序执行的。 但如果此时发生了某...
  • Arduino中断例程及常用arduino开发板中断引脚汇总

    千次阅读 多人点赞 2019-03-04 00:59:59
    文章目录外部中断常用arduino开发板外部中断引脚外部中断程序编写外部中断函数外部中断模式例程定时器中断例程 外部中断 常用arduino开发板外部中断引脚 不同的Arduino开发板外部中断引脚不同,总结常用的有如下几个...
  • Arduino常用函数总汇——中断函数

    千次阅读 2018-11-06 22:33:07
    3、attachInterrupt(interruptnum,function,mode):用于设置外部中断函数  interruptnum:中断源(0或1)  function:中断处理函数的名字  mode:中断触发模式(LOW:低电平触发;CHANGE:...
  •   通过生活中一个简单的例子来说明中断。当你正在家中看书时,突然电话铃响了,你停止看书,去接电话,和来电话的人进行交谈,通话结束后回来继续从...  Arduino 中的中断可以分为两类:外部中断和定时中断。...
  • arduino外部中断与舵机

    千次阅读 2019-04-28 17:43:46
    arduino中的外部中断: 中断模式就是你的中断触发方式。在大多数arduino上有以下四种触发方式: LOW 低电平触发 CHANGE 电平变化,高电平变低电平、低电平变高电平 RISING 上升沿触发 FALLING 下降沿触发 HIGH 高电...
  • Arduino基础入门篇13—外部中断

    千次阅读 多人点赞 2018-09-03 12:50:36
    本篇介绍Arduino外部中断的使用,通过外部中断检测震动开关的触发来控制LED灯亮灭。
  • ESP32 Arduino GPIO 中断研究

    千次阅读 2020-09-05 21:45:01
    外部中断只针对于输入设备,当设备输入时的IO口电平发送变化时,调用相对应的IO的外部中断函数或者寄存器就会进入到IO口的外部中断控制。 当配置完成时,加入需要对外部IO口变化之后进行操作时,通常的单片机需要...
  • Arduino-中断

    2019-05-25 06:17:00
    中断的分类:Arduino中的中断可以分为两类:外部中断和定时中断 外部中断:一般是指由外设发出的中断请求,即中断源在外部。如键盘中断、打印机中断等。外部中断需要外部中断源发出中断请求才能发中断。定时中断:...
  • [Arduino] 外部中断

    2014-04-29 22:25:00
    1.什么是中断? 试想一下,你正在家里吃饭,这时传来了敲门声,虽然你巨饿,虽然面前全是山珍海味,但此时你不得不去开门,同时不得不放停下生命中最重要的事情——吃饭。 打开门后,你发现只是一个查水表的,你...
  • 外部中断:达到实时响应处理事件的效果。 目前Ardinuo UNO引脚只有2个,一个是2号口,一个是3号口 在Ardinuo中中断函数,返回值为空,不能有参数 程序运行截图如下: 当感应到震动后: 这里来看下震动传感器 这里...
  • arduino的基本函数

    千次阅读 2020-07-09 17:34:24
    arduino的基本函数数字I/O模拟I/O高级I/O时间函数数学库随机数位操作中断函数串口通信SPI 数字I/O 1.pinMode(pin,mode) pinMode用以配置引脚为输出或输出模式,它是一个无返回值函数,函数有两个参数pin(表示所要...
  • 三、了解一下arduino中断函数编写 四、上实例【触摸开关(外部中断)开关小灯led】 一、arduino中断模式有啥? 中断模式就是arduino中断触发方式。在大多数arduino上有以下四种触发方式: LOW 低电平触发 ...
  • Arduino ESP32使用外部中断 ESP32支持库版本:3.0.1 esp32型号:esp32 Dev Module 实例程序 // toggles LED when interrupt pin changes state int led = 2;//板载led灯 volatile int state = LOW; const byte ...
  • 外部中断只响应一次,直到任务执行完,并且在任务中存在延时。如何实现开启关闭中断和延时呢?
  • Arduino输入中断

    2018-09-13 10:52:00
    在attachinterrupt时会先执行绑定的函数,然后再返回执行attachinterrupt后的代码,同时外部中断的触发发生时也不会执行对应绑定函数; 将中断设定放置在setup中,同时在触发时用状态变量检测是否执行后续代码,问....
  • arduino 中断

    千次阅读 2017-04-02 07:31:38
    中断函数使用外部中断函数: attachInterrupt(interrupt, function,mode) 外部中断只能用到数字IO口2/3, 表示中断0,1 interrupt 取值范围0,1 function 为中断处理函数 mode: LOW 低电平中断, CHANGE 有...
  • 在 bpibit 上利用 arduino 实现外部中断
  • ARDUINO 中断

    2019-10-03 01:48:37
    设置中断函数 attachInterrupt() attachInterrupt(interrupt, function, mode)描述:当发生外部中断时,调用一个指定函数。...arduino Mege有四个外部中断:数字2(引脚21),3(20针),4...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 640
精华内容 256
关键字:

arduino外部中断函数