17.4. 中断编程¶
在配置每个中断的时候一般有3个编程要点:
使能外设某个中断,这个具体由每个外设的相关中断使能位控制。比如串口有发送完成中断,接收完成中断,这两个中断都由串口控制寄存器的相关中断使能位控制。
初始化NVIC_InitTypeDef结构体,配置中断优先级分组,设置抢占优先级和子优先级,
使能中断请求。NVIC_InitTypeDef结构体在固件库头文件misc.h中定义。
代码清单:中断-3 NVIC初始化结构体¶
1
2
3
4
5
6typedef struct {
uint8_t NVIC_IRQChannel; // 中断源
uint8_t NVIC_IRQChannelPreemptionPriority; // 抢占优先级
uint8_t NVIC_IRQChannelSubPriority; // 子优先级
FunctionalState NVIC_IRQChannelCmd; // 中断使能或者失能
} NVIC_InitTypeDef;
有关NVIC初始化结构体的成员我们一一解释下:
a. NVIC_IROChannel:用来设置中断源,不同的中断中断源不一样,且不可写错,即使写错了程序也不会报错,只会导致不响应中断。
具体的成员配置可参考stm32f10x.h头文件里面的IRQn_Type结构体定义,这个结构体包含了所有的中断源。
代码清单:中断-4 IRQn_Type中断源结构体¶
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21typedef enum IRQn {
//Cortex-M3 处理器异常编号
NonMaskableInt_IRQn = -14,
MemoryManagement_IRQn = -12,
BusFault_IRQn = -11,
UsageFault_IRQn = -10,
SVCall_IRQn = -5,
DebugMonitor_IRQn = -4,
PendSV_IRQn = -2,
SysTick_IRQn = -1,
//STM32 外部中断编号
WWDG_IRQn = 0,
PVD_IRQn = 1,
TAMP_STAMP_IRQn = 2,
// 限于篇幅,中间部分代码省略,具体的可查看库文件stm32f10x.h
DMA2_Channel2_IRQn = 57,
DMA2_Channel3_IRQn = 58,
DMA2_Channel4_5_IRQn = 59
} IRQn_Type;
b. NVIC_IRQChannelPreemptionPriority:抢占优先级,具体的值要根据优先级分组来确定,
具体参考表格 优先级分组真值表 优先级分组真值表 。
c. NVIC_IRQChannelSubPriority:子优先级,具体的值要根据优先级分组来确定,
具体参考表格 优先级分组真值表 优先级分组真值表 。
d. NVIC_IRQChannelCmd:中断使能(ENABLE)或者失能(DISABLE)。
操作的是NVIC_ISER和NVIC_ICER这两个寄存器。
编写中断服务函数
在启动文件startup_stm32f10x_hd.s中我们预先为每个中断都写了一个中断服务函数,只是这些中断函数都是为空,为的只是初始化中断向量表。
实际的中断服务函数都需要我们重新编写,为了方便管理我们把中断服务函数统一写在stm32f10x_it.c这个库文件中。
关于中断服务函数的函数名必须跟启动文件里面预先设置的一样,如果写错,系统就在中断向量表中找不到中断服务函数的入口,
直接跳转到启动文件里面预先写好的空函数,并且在里面无限循环,实现不了中断。