学习单片机一贯的套路,搞完时钟和GPIO就要折腾中断了。
1. 中断和异常的区别
1.1 中断是指系统停止当前正在运行的程序转而其他服务,可能是程序接收了比自身高优先级的请求,或者是人为设置中断,中断是属于正常现象。
1.2 异常是指由于cpu本身故障、程序故障或者请求服务等引起的错误,异常属于不正常现象。
Cortex-M3内核总共支持256个中断,其中包含16个内核异常和240个外部中断,但是各个芯片产商在设计芯片的时候会对CM3内核的芯片进行精简设计,如STM32F103系列,所搭载的异常响应系统,包含10个系统异常和60个外部中断,用一张表将它们管理起来,编 0~15位系统异常,16以上称为外部中断。
系统异常清单:
2.1 CM3核的优先级分组方式
CM3中定义了8个Bit用于设置中断源的优先级,这8个Bit可以分配为:
CM3核的优先级分组方式,使用的设置函数
在LibrariesCMSISCM3CoreSupportcore_cm3.h文件中实现:
该函数写在.h文件中,且声明为内联函数(__INLINE),内联函数跟宏替换差不多,可以避免函数调用的压栈出栈等开销。PriorityGroup的取值为0~7。
2.2 STM32的优先级分组方式
CM3核的优先级分组方式是针对256个中断全部用上的场合,但是Cortex-M3也允许在具有较少中断源时用较少的寄存器位指定中断源的优先级。STM32并没有使用Cortex-M3内核嵌套向量中断全套东西,而是使用了它的一部分:
STM32的优先级分组使用标准库函数
该函数在LibrariesSTM32F10x_StdPeriph_Driversrcmisc.c中实现:
可见,这个函数也是在设置SCB->AIRCR寄存器,只是这里的取值为:
3. NVIC操作相关函数
NVIC的描述结构体在core_cm3.h中:
编程中常用的是ISER、ICER和IP这三个寄存器。ISER和ICER分别用于enable、disable中断,IP用于控制中断优先级。
同在core_cm3.h中,定义了对结构体成员的操作函数,这是针对Cortex-M3内核芯片都适用的函数:
在外设库misc.h定义了针对STM32的NVIC的初始化描述结构体:
misc.c也定义了针对STM32的NVIC的操作函数:
4. EXTI–外部中断和事件控制器
EXTI有20个中断/事件线,每个GPIO都可以被设置为中断/事件的输入线,占用EXTI0~EXTI15,还有另外4根用于特定的外设事件的EXTI16~EXTI19:
这个函数在一般初始化EXTI寄存器时候调用。因为外部中断是GPIO引脚的复用功能,所以同时要开启GPIO复用功能的时钟:
5. EXTI描述结构体的初始化
EXTI描述结构体声明在标准外设库LibrariesSTM32F10x_StdPeriph_Driverincstm32f10x_exti.h中:
与EXTI操作相关的函数有:
获取/清除产生中断的标志的实现是一样的,但是为什么要分成两组函数
也许这是STM32标准外设库设计者出自于为兼容性考虑吧。有的ARM芯片的中断体系分为两层,也就是说中断信 要抵达NVIC需要两层筛选,同理清除中断标志也需要清除两层。但是在CM3核的ARM只设计了一层,STM32为了兼容其他芯片,依旧还是将函数设计成两层,只不过这两层的实现体是一致的。
6. 编程实现按键中断
下来编程操作STM32的中断。未能免俗,还是以按键中断为例。
实验采用正点原子miniSTM32硬件平台,
LED0(PA8)和LED1(PD2)的原理图:
实验实现按键产生外部中断,在中断处理函数中实现反向控制LED灯。编程的要点为:
EXTI用于设置中断源的触发方式、中断/事件类型和具体是哪一个中断源。
中断信 产生后最终传递到NVIC,NVIC控制中断源优先级、中断线通道等,以便比对中断信 、根据优先级调用中断服务函数。
实验采用MDK4集成开发环境,工程的目录结构如下:
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!