STM32 中断

上节补充:

头文件、数据类型及函数声明的添加位置

image-20221225122205578

变量及函数的命名规则

见名知意:利用英文单词或者其缩写形式定义变量或函数,名称要体现变量的作用或函数的功能,切记不要使用拼音来命名。

2. 变量一般采用名词形式命名,多个单词间利用大小写字母作为间隔。全局变量的首字母大写,如KeyFlag;局部变量的首字母小写,如keyFlag,便于区分全局变量和局部变量。

3. 函数一般采用动宾结构命名,首字母大写,也是利用大小写字母作为间隔,如GetValue等。

4. 宏定义和用户自定义数据类型全部采用大写字母,利用下划线作为间隔,如KEY_STATE等。

简介

什么是中断

​ STM32中断是一种电子设备中的功能,它允许设备在执行主程序时暂停执行,以便处理来自外部设备或系统事件的信息。中断是通过向设备发送特殊的信号(称为中断请求)来触发的,该信号会使设备暂停当前的执行流程,转而执行一段特定的代码,称为中断服务程序(ISR)。在中断服务程序执行完毕后,设备会返回到原来的执行流程。

image-20221219205550471
image-20221219205623688

在STM32H750芯片中,你可以使用以下中断源:

  • 外部中断:外部中断可以由芯片的外部中断线触发,支持软件触发、硬件触发和唤醒功能。
  • 定时器中断:STM32H750芯片支持多种定时器,可以用于产生周期性中断。
  • 串口中断:串口中断可以用于响应串口接收到的数据。
  • ADC中断:ADC中断可以用于响应ADC转换完成的信息。

具体的步骤包括:

  1. 配置中断源:在芯片的外设模块(如定时器、串口)中启用中断功能。
  2. 定义中断服务程序:编写中断服务程序,该程序在中断触发时会被执行。
  3. 配置中断优先级:设置中断优先级,以便在多个中断同时发生时能够正确处理。
  4. 启用中断:在主程序中启用中断功能,使得芯片能够响应中断请求。
  5. 开启总中断:在主程序的最后开启总中断,使得芯片开始响应中断请求。

中断优先级

​ 中断优先级是指在微控制器中,在多个中断之间进行调度时,规定哪个中断优先级更高。当微控制器处理多个中断时,优先级较高的中断会优先被处理,优先级较低的中断则要等待优先级较高的中断处理完毕之后才能被处理。

​ 在微控制器中,中断优先级可以分为若干个级别,每个级别都有一个对应的数值。通常,数值越小,优先级越高。例如,在 STM32H750 微控制器中,中断优先级可以分为 0 到 15 共 16 个级别,数值为 0 的优先级最高,数值为 15 的优先级最低。


HAL库的中断封装

HAL库的中断封装

image-20221220200649608

HAL库对中断的封装处理

一:统一规定处理各个外设的中断服务程序HAL_PPP_IRQHandler

PPP代表外设名称

二:在中断服务程序HAL_PPP_IRQHandler完成了中断标志的判断和清除

三:将中断中需要执行的操作以回调函数的形式提供给用户

由外设初始化、中断、处 理完成/出错触发的函数

由CubeMX生成的工程中与中断相关的编程文件

启动文件: startup_stm32fxxx 或 startup_stm32hxxx

  1. 在该文件中,预先为每个中断编写了一个中断服务程序,只是这些中断服务程序都是死循环,目的只是初始化中断向量表;
  2. 中断服务程序的属性定义为“weak”。weak属性的函数表示:如果该函数没有在其他文件中定义,则使用该函数;如果用户在其他地方定义 了该函数,则使用用户定义的函数

中断服务程序文件:stm32fxxx_it.c 或 startup_stm32hxxx_it.c

  1. 用于存放各个中断的中断服务程序;

  2. 在使用CubeMX软件进行初始化配置时,如果使能了某一个外设的中断功能,那么在生成代码时,相对应的外设中断服务程序HAL_PPP_IRQHandler就会自动添加到该文件中,用户只需要在该函数中添加相应的中断处理代码即可。

外部中断所对应的中断服务程序

外部中断线 中断服务程序的函数名称
外部中断线1(EXTI Line 1) EXTI1_IRQHandler
外部中断线2(EXTI Line 2) EXTI2_IRQHandler
外部中断线3(EXTI Line 3) EXTI3_IRQHandler
外部中断线4(EXTI Line 4) EXTI4_IRQHandler
外部中断线5~9(EXTI Line[9:5] ) EXTI9_5_IRQHandler
外部中断线10~ 15(EXTI Line[15:10] ) EXTI15_10_IRQHandler

stm32h7xx_it.c文件中的外部中断服务程序

image-20221220201510816

HAL库的外部中断处理流程

image-20221220202231156

引脚初始化数据类型

image-20221220202435635
成员变量Mode的取值范围
宏常量定义 含义
GPIO_MODE_IT_RISING 上升沿触发
GPIO_MODE_IT_FALLING 下降沿触发
GPIO_MODE_IT_RISING_FALLING 双边沿触发

外部中断通用处理函

image-20221220202701381

外部中断回调函数

image-20221220202742739

任务1:按键中断的方式 控制LED

配置GPIO口

image-20221225115738703

电路图

PC13 为按键有下拉电阻

PE3 为输出的LED灯

设置输出LED

设置为 output

用户标签为LED

image-20221225115837063
image-20221225120304510

设置按键

选择GPIO_EXTI13

引脚为外部中断 功能,与外部中 断线EXTI13连接

用户标签为KEY

image-20221225115935019

在出现的引脚列表中单 击需要配置的引脚PC13

我的PC13 当按下为高电平 松开为低电平 所以我设置为上升沿触发

GPIO mode 为触发模式

常用的 就是前三个 分别是:

依次是 上升沿触发 下降沿触发 双边沿触发(上升下降触发)

image-20221225120903522
image-20221225120648026

使能中断

还是在刚才的窗口中 点击NVIC

使能引脚对应的外部中断线EXTI Line[15:10]

image-20221225121244284

代码编写

  1. 编写回调函数

尽量将直接写的代码函数等写在 code Begin下

1
2
3
4
5
6
7
/* USER CODE BEGIN 4 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
if (GPIO_Pin == KEY_Pin){
HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
}
}
/* USER CODE END 4 */

任务2:改变指示灯闪烁频率

声明表示闪烁速度的变量

1
2
3
/* USER CODE BEGIN PV */
uint8_t Speed = 0 ; //声明表示速度的变量
/* USER CODE END PV */

在主函数while循环中 判断Speed的速度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
while (1)
{
/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */
switch (Speed) {
case 0: //当速度为 0 LED每隔100ms 闪烁
HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
HAL_Delay(100);
break;
case 1://当速度为 1 LED每隔500ms 闪烁
HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
HAL_Delay(500);
break;
case 2://当速度为 2 LED每隔1000ms 闪烁
HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
HAL_Delay(1000);
break;
}
}
/* USER CODE END 3 */

在中断的回调函数中修改Speed变量的值

1
2
3
4
5
6
7
8
/* USER CODE BEGIN 4 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
if (GPIO_Pin == KEY_Pin){
Speed++; //修改Speed 的值
if(Speed == 3) Speed =0; //Speed 的取值范围为0 ~2
}
}
/* USER CODE END 4 */