“Arduino定时器中断”的版本间的差异
来自YFRobotwiki
(以“当你想让代码在一个固定的时间间隔后执行时,你可以很容易的用delay()函数来实现。但是,这只是让程序暂停一个特定的时...”为内容创建页面) |
|||
第15行: | 第15行: | ||
<pre > | <pre > | ||
− | /* | + | /* |
− | timer1 | + | timer1 中断实例 |
− | LED闪光灯每秒闪亮一下 | + | LED闪光灯每秒闪亮一下 |
− | #define | + | */ |
− | int | + | |
− | void | + | #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() { //你自己的程序 }