Arduino对于内部中断有开源库,对于外部中断官方也有函数,这一部分算是补全这个系列吧
1.中断类型
- RESET,复位中断
- INT0、INT1,外部中断
- TIMER0、1、2,定时器中断,用于实现内部中断(定时中断)
- ADC,模数转换完成中断
- ANALOG COMP,模拟比较器中断
2.中断函数格式
ISR("中断名称"){
//中断函数实现
}
当捕捉到相应的中断时,会进入到相应的中断函数。
3.定时中断
注:参考本专栏中PWM相关博客
3.1 TIMSK
- OCIExB:该位置1且使能全局中断时,相应的定时器比较匹配B使能,如果出现比较匹配,则触发中断。
- OCIExA:该位置1且使能全局中断时,相应的定时器比较匹配A使能,如果出现比较匹配,则触发中断。
- TOIEx:该位置1且使能全局中断时,相应的定时器溢出中断使能,如果发生溢出,则触发中断。
- ICIE1:该位置1且使能全局中断时,定时器1输入捕获中断使能。
3.2 定时中断示例
3.2.1 示例1
// Timer2定时中断
int tick = 0; //计数值
void setup(){
Serial.begin(115200); // 初始化串口
TIMSK2 = _BV(TOIE2); // 设置定时器溢出中断
TCCR2A = _BV(WGM20); // 相位矫正模式
TCCR2B = _BV(CS22) | _BV(CS21) | _BV(CS20); // 1024分频
}
/*
时间计算:16000000/1024/256/2 = 30.5HZ 2/61秒
*/
void loop(){
}
ISR(TIMER2_OVF_vect){ // 设置定时器2溢出中断
Serial.print("timer2 ");
Serial.println(tick++);
}
3.2.2 示例2
// Timer2定时中断
int tick = 0; //计数值
void setup(){
Serial.begin(115200); // 初始化串口
TIMSK2 = _BV(OCIE2A); // 设置定时器比较匹配A中断
TCCR2A = _BV(WGM21) | _BV(WGM20); // 快速PWM模式
TCCR2B = _BV(CS22) | _BV(CS21) | _BV(CS20); // 1024分频
OCR2A = 255; // 设置多少都无所谓
}
/*
注:比较匹配中断最好不要使用相位矫正模式,且OCR的设置大小对于频率区别也不大
时间计算:16000000/1024/256 = 61HZ 1/61秒
*/
void loop(){
}
ISR(TIMER2_COMPA_vect){ // 设置定时器比较匹配A中断
Serial.print("timer2 ");
Serial.println(tick++);
}
3.2.3 示例3
// Timer2定时中断
int tick = 0; //计数值
void setup(){
Serial.begin(115200); // 初始化串口
TIMSK2 = _BV(TOIE2); // 设置定时器溢出中断
TCCR2A = _BV(WGM21) | _BV(WGM20); // OCRA设置的快速PWM模式
TCCR2B = _BV(WGM22) | _BV(CS22) | _BV(CS21) | _BV(CS20); // 1024分频
OCR2A = 200; // 可以调节中断的频率
}
/*
时间计算:16000000/1024/200 = 78HZ 1/78秒
*/
void loop(){
}
ISR(TIMER2_OVF_vect){ // 设置定时器2溢出中断
Serial.print("timer2 ");
Serial.println(tick++);
}
注:Timer1也是同样的道理,但是Timer1的功能更强大;对于Timer0,最好不要操作,否则会影响一些计时函数,当然,如果你的项目中没有使用计时函数,也可以修改Timer0