单片机的中断可概述为:由于某一随机事件的发生,单片机暂停原程序的运行,转去执行另一程序(随机事件),处理完毕后又自动返回原程序继续运行,其发生过程如图1-48所示,其中中断源、主程序、中断服务程序简述如下。
图1-48 中断发生的过程
(1)中断源:引起中断的原因,或能发生中断申请的来源。
(2)主程序:单片机现在运行的程序。
(3)中断服务程序:处理中断事件的程序。
1.interrupts()和nolnterrupts()
interrupts和nolnterrupts函数在Arduino中负责打开和关闭总中断,函数无返回值,无参数,同样可在文件 wiring.h 中查看到函数原型,如下:
#define interrupts()sei()
#define nointerrupts()cli()
2.attachlnterrupt(interrupt,function,mode)
attachlnterrupt 函数用于设置外部中断,函数有3个参数:interrupt、function和mode,分别表示中断源、中断处理函数、触发模式。参数中断源可选值0或1,在Arduino中一般对应2号和3号数字引脚;参数中断处理函数用来指定中断的处理函数,参数值为函数的指针,触发模式有4种类型:LOW(低电平触发)、CHANGE(变化时触发)、RISNG(低电平变为高电平触发)、FALLING(高电平变为低电平触发)。
下面的例子是通过外部引脚触发中断函数,然后控制13号引脚LED的闪烁。
int pin =13
volatile int state=LOW
void setup()
{
pinmode(pin,OUTPUT);
attachinterrupt(0,blink,CHANGE); //中断源:1
//中断处理函数:blink())
//触发模式:CHANGE(变化时触发)
}
void loop()
{
digitalwrite(pin,state);
}
//中断处理函数
void blink()
{
state=lstate;
}
在使用attachlnterrupt函数时要注意以下几点:
在中断函数中delay函数不能使用。
使用millis函数始终返回进入中断前的值。
如果读取串口数据,可能会丢失。
中断函数中使用的变量需要定义为volatile型。
attachInterrupt的函数原型可在文件WInterrupts.c中找到,如下所示:
void attachinterrupt(uint8-t interruptnum,void (*userfunc)(void),int mode)
{
if(interruptnum<EXTERNAL-NUM-INTERRUPTS)
{
intfunc(interruptnum)=userfunc;
switch(interruptnum)
{
case 0:
EICRA=(EICRA &-((1<<ISC00)
|(1<<isc11)))|(MODE<<ISC10);
EIMSK|(1<<INT1):
break;
}
}
}
另外,还有detachInterrupt 函数用于取消中断,参数interrupt表示所要取消的中断源,函数的定义如下:
void detachinterrupt(uint8-t interruptnum)
{
if(interruptnum<EXTERNAL-NUM-INTERRUPTS)
{
switch (interruptnum)
{
case 0:
EIMSK&-(1<<INT0);
break;
case 1:
EIMSK&-(1<<INT0);
break;
}
intfunc[interruptnum]=0;
}
}
3.datachlnterrupt(interrupt)
datachlnterrupt函数用于取消中断,参数interrupt表示所要取消的中断源。