STM32单片机中断机制深入剖析:从中断向量表到中断优先级,全面掌握中断机制
发布时间: 2024-07-02 11:07:17 阅读量: 221 订阅数: 97
STM32中断机制
![STM32单片机中断机制深入剖析:从中断向量表到中断优先级,全面掌握中断机制](https://img-blog.csdnimg.cn/3f64227844dd43ecb2f6eddabb3ccb34.png)
# 1. 中断机制基础**
中断机制是微控制器中一种重要的机制,它允许外部事件或内部条件触发程序执行的暂停和恢复。在STM32单片机中,中断机制由专门的硬件模块管理,提供高效和可配置的中断处理能力。
**中断的分类:**
* **外部中断:**由外部引脚上的信号触发,如按钮按下或传感器输入。
* **内部中断:**由内部事件触发,如定时器溢出或数据传输完成。
**中断处理过程:**
当发生中断时,STM32单片机暂停当前执行的程序,跳转到中断向量表中指定的中断服务程序(ISR)。ISR负责处理中断事件,执行必要的操作,然后返回到主程序。
# 2. 中断向量表与中断服务程序
### 2.1 中断向量表结构
中断向量表是存储中断服务程序入口地址的数组。STM32单片机的中断向量表位于内存地址 0x0000 0000,共包含 256 个 32 位的入口地址。每个入口地址对应一个中断源,当该中断源触发时,CPU 将跳转到相应的入口地址执行中断服务程序。
中断向量表结构如下:
| 中断源 | 入口地址 |
|---|---|
| 复位 | 0x0000 0004 |
| NMI | 0x0000 0008 |
| 硬故障 | 0x0000 000C |
| MemManage | 0x0000 0010 |
| BusFault | 0x0000 0014 |
| UsageFault | 0x0000 0018 |
| SVC | 0x0000 001C |
| DebugMon | 0x0000 0020 |
| PendSV | 0x0000 0024 |
| SysTick | 0x0000 0028 |
| ... | ... |
### 2.2 中断服务程序编写
中断服务程序是响应中断请求的代码段。中断服务程序的编写需要遵循以下规则:
- 中断服务程序必须以 `__attribute__((interrupt))` 声明,表明该函数是一个中断处理函数。
- 中断服务程序必须有一个参数,该参数为中断源号。
- 中断服务程序必须以 `__attribute__((naked))` 声明,表明该函数没有函数序言和尾声。
- 中断服务程序必须使用汇编指令 `push` 和 `pop` 保存和恢复寄存器。
- 中断服务程序必须使用汇编指令 `bl` 调用 C 语言函数。
以下是一个中断服务程序的示例:
```c
__attribute__((interrupt))
void USART1_IRQHandler(void)
{
__attribute__((naked))
{
// 保存寄存器
push({r0, r1, r2, r3, r12, lr})
// 调用 C 语言函数处理中断
bl USART1_IRQHandler_C
// 恢复寄存器
pop({r0, r1, r2, r3, r12, lr})
// 返回中断向量表
bx lr
}
}
```
在 C 语言函数 `USART1_IRQHandler_C` 中,可以编写具体的中断处理逻辑。
# 3.1 中断优先级设置
STM32单片机的中断优先级分为16个等级,其中0级优先级最高,15级优先级最低。中断优先级可以通过NVIC寄存器进行设置。
**NVIC寄存器结构**
```
typedef struct {
__IO uint32_t ISER[8]; /* Interrupt Set Enable Register */
__IO uint32_t ICER[8]; /* Interrupt Clear Enable Register */
__IO uint32_t ISPR[8]; /* Interrupt Set Pending Register */
__IO uint32_t ICPR[8]; /* Interrupt Clear Pending Register */
__IO uint32_t IABR[8]; /* Interrupt Active Bit Register */
__IO uint8_t IP[80]; /* Interrupt Priority Register (80 interrupts) */
__IO uint32_t STIR; /* Software Trigger Interrupt Register */
} NVIC_TypeDef;
```
**中断优先级设置代码**
```c
/* 设置中断优先级 */
NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority);
/* 获取中断优先级 */
uint32_t NVIC_GetPriority(IRQn_Type IRQn);
```
**参数说明**
* **IRQn:** 中断号
* **priority:** 优先级,取值范围0~15
**代码逻辑**
* `NVIC_SetPriority()`函数将指定中断号的中断优先级设置为指定的优先级。
* `NVIC_GetPriority()`函数获取指定中断号的中断优先级。
### 3.2 中断嵌套管理
STM32单片机支持中断嵌套,即在处理一个中断时可以被更高优先级的中断打断。中断嵌套可以通过NVIC寄存器进行管理。
**NVIC寄存器结构**
```
typedef struct {
__IO uint32_t ISER[8]; /* Interrupt Set Enable Register */
__IO uint32_t ICER[8]; /* Interrupt Clear Enable Register */
__IO uint32_t ISPR[8]; /* Interrupt Set Pending Register */
__IO uint32_t ICPR[8]; /* Interrupt Clear Pending Register */
__IO uint32_t IABR[8]; /* Interrupt Active Bit Register */
__IO uint8_t IP[80]; /* Interrupt Priority Register (80 interrupts) */
__IO uint32_t STIR; /* Software Trigger Interrupt Register */
__IO uint32_t ICER[4]; /* Interrupt Clear Enable Register */
__IO uint32_t ISPR[4]; /* Interrupt Set Pending Register */
__IO uint32_t ICPR[4]; /* Interrupt Clear Pending Register */
__IO uint32_t IABR[4]; /* Interrupt Active Bit Register */
__IO uint8_t IP[24]; /* Interrupt Priority Register (24 interrupts) */
} NVIC_Type;
```
**中断嵌套管理代码**
```c
/* 设置中断嵌套 */
NVIC_SetPriorityGrouping(uint32_t priorityGrouping);
/* 获取中断嵌套 */
uint32_t NVIC_GetPriorityGrouping();
```
**参数说明**
* **priorityGrouping:** 优先级分组,取值范围0~7
**代码逻辑**
* `NVIC_SetPriorityGrouping()`函数设置中断嵌套的优先级分组。优先级分组决定了中断优先级和子优先级的分配方式。
* `NVIC_GetPriorityGrouping()`函数获取中断嵌套的优先级分组。
# 4. 中断响应与中断服务
### 4.1 中断响应过程
当一个中断事件发生时,STM32单片机将执行以下中断响应过程:
1. **中断请求检测:**中断控制器检测到一个中断请求信号,并确定中断源。
2. **中断向量表查找:**中断控制器根据中断源地址查找中断向量表中的相应中断服务程序入口地址。
3. **程序计数器更新:**程序计数器(PC)更新为中断服务程序入口地址,开始执行中断服务程序。
4. **中断屏蔽:**中断控制器屏蔽当前中断源,防止在中断服务程序执行期间再次触发相同中断。
5. **中断标志清除:**中断控制器清除中断源的中断标志位,表示中断事件已被处理。
### 4.2 中断服务流程
中断服务程序是响应中断事件的代码段,通常包含以下步骤:
1. **保存寄存器:**中断服务程序开始时,保存当前程序状态的寄存器值,包括程序计数器(PC)、栈指针(SP)、通用寄存器(R0-R15)等。
2. **处理中断事件:**根据中断源,执行相应的处理逻辑,例如读取输入数据、更新状态变量、发送数据等。
3. **恢复寄存器:**中断服务程序结束时,恢复之前保存的寄存器值,恢复中断前的程序状态。
4. **中断返回:**执行一条中断返回指令(RET),将程序计数器更新为中断发生前的地址,继续执行主程序。
### 代码示例
以下代码示例演示了一个中断服务程序:
```c
// 中断服务程序
void SysTick_Handler(void) {
// 保存寄存器
__asm volatile("push {r0-r3, r12}");
// 处理中断事件
// ...
// 恢复寄存器
__asm volatile("pop {r0-r3, r12}");
// 中断返回
__asm volatile("bx lr");
}
```
### 流程图
下图展示了中断响应和中断服务流程:
```mermaid
sequenceDiagram
participant MCU
participant Interrupt Controller
MCU->Interrupt Controller: Interrupt Request
Interrupt Controller->MCU: Interrupt Vector Table Lookup
MCU->Interrupt Controller: Program Counter Update
Interrupt Controller->MCU: Interrupt Masking
Interrupt Controller->MCU: Interrupt Flag Clearing
MCU->Interrupt Controller: Interrupt Service Routine Entry
MCU->Interrupt Controller: Register Saving
MCU->Interrupt Controller: Interrupt Event Handling
MCU->Interrupt Controller: Register Restoring
MCU->Interrupt Controller: Interrupt Return
```
# 5. 中断机制在STM32单片机中的应用
### 5.1 外部中断应用
**5.1.1 外部中断简介**
外部中断是STM32单片机通过外部引脚接收外部事件的机制。它允许单片机在检测到外部信号变化时触发中断响应。外部中断可以分为两种类型:上升沿触发和下降沿触发。
**5.1.2 外部中断配置**
配置外部中断需要以下步骤:
1. **使能时钟:**为外部中断引脚所在的GPIO端口使能时钟。
2. **配置GPIO引脚:**将外部中断引脚配置为输入模式,并选择触发方式(上升沿或下降沿)。
3. **配置NVIC:**在NVIC中使能外部中断,并设置优先级。
**5.1.3 外部中断服务程序**
外部中断服务程序是响应外部中断事件的函数。它通常包含以下步骤:
1. **读取中断标志位:**读取外部中断标志位,确定触发中断的引脚。
2. **清除中断标志位:**清除外部中断标志位,以允许后续中断事件触发。
3. **执行中断处理:**执行与中断事件相关的处理操作。
### 5.2 定时器中断应用
**5.2.1 定时器中断简介**
定时器中断是STM32单片机使用定时器外设生成的定期中断。它允许单片机在特定时间间隔内触发中断响应。定时器中断可以用于实现各种功能,例如定时、计数和脉宽调制。
**5.2.2 定时器中断配置**
配置定时器中断需要以下步骤:
1. **使能时钟:**为定时器外设使能时钟。
2. **配置定时器:**设置定时器的工作模式、时钟源和计数值。
3. **配置NVIC:**在NVIC中使能定时器中断,并设置优先级。
**5.2.3 定时器中断服务程序**
定时器中断服务程序是响应定时器中断事件的函数。它通常包含以下步骤:
1. **读取中断标志位:**读取定时器中断标志位,确定触发中断的定时器。
2. **清除中断标志位:**清除定时器中断标志位,以允许后续中断事件触发。
3. **执行中断处理:**执行与定时器中断事件相关的处理操作。
### 5.3 串口中断应用
**5.3.1 串口中断简介**
串口中断是STM32单片机使用串口外设生成的接收和发送中断。它允许单片机在接收到数据或发送完数据时触发中断响应。串口中断可以用于实现各种功能,例如数据传输、调试和通信。
**5.3.2 串口中断配置**
配置串口中断需要以下步骤:
1. **使能时钟:**为串口外设使能时钟。
2. **配置串口:**设置串口的工作模式、波特率和数据格式。
3. **配置NVIC:**在NVIC中使能串口中断,并设置优先级。
**5.3.3 串口中断服务程序**
串口中断服务程序是响应串口中断事件的函数。它通常包含以下步骤:
1. **读取中断标志位:**读取串口中断标志位,确定触发中断的事件(接收或发送)。
2. **清除中断标志位:**清除串口中断标志位,以允许后续中断事件触发。
3. **执行中断处理:**执行与串口中断事件相关的处理操作,例如接收数据或发送数据。
# 6. 中断机制的优化与调试**
### 6.1 中断优化策略
中断优化旨在提高中断响应速度和系统效率,主要策略包括:
- **减少中断服务程序中的代码量:**仅执行必要的任务,避免冗余操作。
- **使用中断优先级:**合理设置中断优先级,确保重要中断优先响应。
- **使用中断嵌套:**允许高优先级中断中断低优先级中断,提高响应速度。
- **使用DMA(直接内存访问):**将数据传输从CPU卸载到DMA控制器,减少CPU开销。
- **使用中断分组:**将相关中断分组,方便管理和优化。
### 6.2 中断调试技巧
中断调试需要仔细分析和排查,常用技巧包括:
- **使用调试器:**设置断点、单步执行,跟踪中断响应和服务过程。
- **使用逻辑分析仪:**捕获中断信号,分析时序和触发条件。
- **使用printf输出:**在中断服务程序中输出调试信息,了解中断触发和执行情况。
- **使用中断标志寄存器:**检查中断标志寄存器,确定中断源和状态。
- **使用中断优先级寄存器:**检查中断优先级设置,确保正确配置。
0
0