在一次篇文章里,我们讨论了如何使用引脚中断,这次我们来看看如何实现一个串口中断。如果是刚接触处理器编程的朋友, 一定记得,在通往“一灯大师”之路(三)中,其它的串口编程函数还都好理解,唯独最后一个attach (Callback< void()> func, IrqType type=RxIrq),好像不是很明白。其实这个就是串口的中断功能。第一个参数func就是中断发生时所调用的中断服务函数,IrqType就是何种类型的中断,对应串口,最常见的是接收中断和发送中断。
在前面的例子()中,我们是通过以下语句了判断串口中是否数据待接收的:
if(pc.readable())
效率似乎有点低,所以我们改一下,用中断的方式去实现:
#include"mbed.h"
Serialpc(SERIAL_TX,SERIAL_RX);
DigitalOutmyled(LED1);
voidUART_Rx_irq()//中断服务函数
{
charrecd;
if(pc.readable()){//检查是否有字符待读取
recd=pc.getc();//有则读取
if(recd=='o')//判断读取到的字符是否为字母o
myled=1;//是则点亮LED
else
myled=;//否则关闭LED
}
}
intmain()
{
pc.baud(9600);
pc.attach(&UART_Rx_irq,SerialBase::RxIrq);//指明中断服务函数以及中断类型,RX是接收中断
while(1){
}
}
可以发现,代码其实并没有变,只是将接收部分由while(1)里面移到中断服务函数void UART_Rx_irq()里。但执行上却把CPU的资源让了出来,这样只要没有数据需要接收,主程序可以去执行其它任务。
关于中断,还有另外一个问题是,如果同时来两个中断,CPU该去执行谁呢,这就涉及到了中断优先级的问题了,mbed里关于中断的,在如下网址中有描述:
https://os.mbed.com/users/screamer/code/mbed/docs/aff670d0d510/group__CMSIS__Core__NVICFunctions.html
这里我们只用它的优先级设置的函数是:
NVIC_SetPriority (IRQn_TypeIRQn, uint32_t priority)
IRQn表示中断类型,priority表示中断优先级,用数字表示,数字越低,优先级越高。所以如果同时有按键中断和串口中断(这两中断默认优先级是一样的),想把串口调高点,可以用以下两行语句设置:
NVIC_SetPriority(UART0_IRQn, 6);
NVIC_SetPriority(EINT3_IRQn, 10);
那如果CPU在进行一项重要的任务,不想被打断,比如对flash擦写操作,因为一旦中途停止,极有可能造成flash的损坏。这里就用到了关闭和开启中断的操作:
__disable_irq():禁止所有可屏蔽中断
__enable_irq():允许所有未屏蔽中断
其实关于中断还有很多操作,但这里已经涉及到ARM的中断系统,属于比较底层的东西,有点超出本教程最初的设定的受众范围。所以就先讲到这,以且有机会再谈。
领取专属 10元无门槛券
私享最新 技术干货