Arduino定时器中断:修訂版本之間的差異
出自YFRobotwiki
第 10 行: | 第 10 行: | ||
"Arduino Mega"板有另外三个可使用的timer3/4/5,这些定时器都是16位定时器。 | "Arduino Mega"板有另外三个可使用的timer3/4/5,这些定时器都是16位定时器。 | ||
+ | |||
+ | |||
+ | ---- | ||
+ | PWM和定时器 | ||
+ | 定时器和PWM输出之间存在固定的关系。 | ||
+ | 当您查看数据手册或处理器的引脚分配时,这些具有PWM功能的引脚具有OCRxA,OCRxB或OCRxC等名称(其中x表示定时器编号0..5)。PWM功能通常与其他引脚功能共享。 | ||
+ | Arduino有3个定时器和6个PWM输出引脚。定时器和PWM输出之间的关系是: | ||
+ | * 引脚5和6:由timer0控制 | ||
+ | * 引脚9和10:由timer1控制 | ||
+ | * 引脚11和3:由timer2控制 | ||
+ | |||
+ | 在Arduino Mega上我们有6个定时器和15个PWM输出: | ||
+ | * 引脚4和13:由timer0控制 | ||
+ | * 引脚11和12:由timer1控制 | ||
+ | * 引脚9和10:由timer2控制 | ||
+ | * 引脚2,3和5:由定时器3控制 | ||
+ | * 引脚6,7和8:由定时器4控制 | ||
+ | * 引脚46,45和44 ::由定时器5控制 | ||
+ | ---- | ||
在以下的例子中,我们将在我们的中断使用timer1。显然,如果你用了Servo()库就会有冲突,所以你应该选择其他timer。 | 在以下的例子中,我们将在我们的中断使用timer1。显然,如果你用了Servo()库就会有冲突,所以你应该选择其他timer。 |
2019年7月18日 (四) 18:02的修訂版本
當你想讓代碼在一個固定的時間間隔後執行時,你可以很容易的用delay()函數來實現。但是,這只是讓程序暫停一個特定的時間段。特別是如果你需要同時讓處理器做其他處理時,這麼做同時也是一種浪費
這時候就是定時器(Timer)和中斷(Interrupt)的用武之地了。
Arduino UNO有三個timer
- timer0 - 一個被Arduino的 delay() ,millis() 和 micros()使用的8位定時器
- timer1 - 一個被Arduino的 Servo()庫使用的16位定時器(Servo 庫在Arduino Mega上使用timer5)
- timer2 - 一個被Arduino的 Tone()庫使用的8位定時器
"Arduino Mega"板有另外三個可使用的timer3/4/5,這些定時器都是16位定時器。
PWM和定時器 定時器和PWM輸出之間存在固定的關係。 當您查看數據手冊或處理器的引腳分配時,這些具有PWM功能的引腳具有OCRxA,OCRxB或OCRxC等名稱(其中x表示定時器編號0..5)。PWM功能通常與其他引腳功能共享。 Arduino有3個定時器和6個PWM輸出引腳。定時器和PWM輸出之間的關係是:
- 引腳5和6:由timer0控制
- 引腳9和10:由timer1控制
- 引腳11和3:由timer2控制
在Arduino Mega上我們有6個定時器和15個PWM輸出:
- 引腳4和13:由timer0控制
- 引腳11和12:由timer1控制
- 引腳9和10:由timer2控制
- 引腳2,3和5:由定時器3控制
- 引腳6,7和8:由定時器4控制
- 引腳46,45和44 ::由定時器5控制
在以下的例子中,我們將在我們的中斷使用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() { //你自己的程序 }