“Arduino定时器中断”的版本间的差异

来自YFRobotwiki
跳转至: 导航搜索
(以“当你想让代码在一个固定的时间间隔后执行时,你可以很容易的用delay()函数来实现。但是,这只是让程序暂停一个特定的时...”为内容创建页面)
 
第15行: 第15行:
  
 
<pre >
 
<pre >
/*
+
/*
timer1 中断实例
+
  timer1 中断实例
LED闪光灯每秒闪亮一下 */   
+
  LED闪光灯每秒闪亮一下
#define  ledPin 13 //设置输出口为13口
+
*/
int  timer1_counter;
+
 
void  setup()
+
#define ledPin 13    //设置输出口为13口
 +
int timer1_counter;
 +
 
 +
void setup() {
 +
 
 +
  pinMode(ledPin, OUTPUT);
 +
 
 +
  //初始化定时器1
 +
  noInterrupts(); //禁止所有中断
 +
  TCCR1A = 0;
 +
  TCCR1B = 0;
 +
 
 +
  //为我们的中断设置timer1_counter为正确的时间间隔
 +
  // timer1_counter = 64911;    //预加载timer1为65536-16MHz/256/100Hz
 +
  // timer1_counter = 64286;    //预加载timer1为65536-16MHz/256/50HZ
 +
  timer1_counter = 34286;    //预加载timer1为65536-16MHz/256/2Hz
 +
  TCNT1 = timer1_counter;    //预加载timer
 +
  TCCR1B |= (1 << CS12);      //256 分频器(256 prescaler?)
 +
  TIMSK1 |= (1 << TOIE1);    //启用定时器溢出中断
 +
  interrupts();              //允许所有中断
 +
}
 +
 
 +
ISR(TIMER1_OVF_vect) {        //常规中断服务
 +
  TCNT1 = timer1_counter;    //预加载timer digitalWrite(ledPin, digitalRead(ledPin) ^ 1);
 +
}
 +
 
 +
void loop() {
 +
  //你自己的程序
 +
}
  
 
</pre>
 
</pre>

2019年7月18日 (四) 17:26的版本

当你想让代码在一个固定的时间间隔后执行时,你可以很容易的用delay()函数来实现。但是,这只是让程序暂停一个特定的时间段。特别是如果你需要同时让处理器做其他处理时,这么做同时也是一种浪费

这时候就是定时器(Timer)和中断(Interrupt)的用武之地了。

Arduino UNO有三个timer

timer0 - 一个被Arduino的 delay() ,millis() 和 micros()使用的8位定时器  timer1 - 一个被Arduino的 Servo()库使用的16位定时器 timer2 - 一个被Arduino的 Tone()库使用的8位定时器  "Arduino Mega"板有另外三个可使用的timer3,4,5,而不是只有timer0,1,2

在以下的例子中,我们将在我们的中断使用timer1。显然,如果你用了Servo()库就会有冲突,所以你应该选择其他timer。

下面是一个基本的中断驱动程序。这是基本的LED闪光灯程序。但是现在我们用中断而不是delay()来每半秒开启和关闭LED灯一次,从而实现让LED每秒闪一次的效果。

/*
  timer1 中断实例
  LED闪光灯每秒闪亮一下
*/

#define ledPin 13     //设置输出口为13口
int timer1_counter;

void setup() {

  pinMode(ledPin, OUTPUT);

  //初始化定时器1
  noInterrupts(); //禁止所有中断
  TCCR1A = 0;
  TCCR1B = 0;

  //为我们的中断设置timer1_counter为正确的时间间隔
  // timer1_counter = 64911;    //预加载timer1为65536-16MHz/256/100Hz
  // timer1_counter = 64286;    //预加载timer1为65536-16MHz/256/50HZ
  timer1_counter = 34286;     //预加载timer1为65536-16MHz/256/2Hz
  TCNT1 = timer1_counter;     //预加载timer
  TCCR1B |= (1 << CS12);      //256 分频器(256 prescaler?)
  TIMSK1 |= (1 << TOIE1);     //启用定时器溢出中断
  interrupts();               //允许所有中断
}

ISR(TIMER1_OVF_vect) {        //常规中断服务
  TCNT1 = timer1_counter;     //预加载timer digitalWrite(ledPin, digitalRead(ledPin) ^ 1);
}

void loop() {
  //你自己的程序
}