当前位置: 首页 > ops >正文

STM32中断

STM32 GPIO外部中断简图

在这里插入图片描述

中断向量表

定义一块固定的内存,以4字节对齐,存放各个中断服务函数程序的首地址
中断向量表定义在启动文件,当发生中断,CPU会自动执行对应的中断服务函数
在这里插入图片描述
中断向量表以及中断函数
在这里插入图片描述

NVIC嵌套向量中断控制器

在这里插入图片描述

NVIC工作原理

在这里插入图片描述

STM32中断优先级基本概念

1,抢占优先级(pre):高抢占优先级可以打断正在执行的低抢占优先级中断
2,响应优先级(sub):当抢占优先级相同时,响应优先级高的先执行,但是不能互相打断
3,抢占和响应都相同的情况下,自然优先级越高的,先执行
4,自然优先级:中断向量表的优先级
5,数值越小,表示优先级越高

自然优先级:
在这里插入图片描述
上面的就是自然优先级,在stm32中,中断是数字越小,优先级越高,在FreeRtos中任务优先级数字越大,优先级越高

STM32中断优先级分组

在这里插入图片描述
STM32中断优先级举例(假设分组是2),也就是上面的2位(4个)抢占优先级,2位(4个)响应优先级
在这里插入图片描述

中断和事件

中断和事件的理解:
中断:要进入NVIC,有相应的中断服务函数,需要CPU处理
事件:不进入NVIC,仅用于内部硬件自动控制的,如:TIM、DMA、ADC

外部中断

在这里插入图片描述
F1/F4/F7系列
每条EXTI线都可以单独配置:选择类型(中断或者事件)、触发方式(上升沿,下降沿或者双边沿触发)、支持软件触发、开启/屏蔽、有挂起状态位
H7系列
由其它外设对 EXTI 产生的事件分为可配置事件和直接事件。
可配置事件:简单概括,基本和F1/F4/F7系列类似
直接事件:固定上升沿触发、不支持软件触发、无挂起状态位(由其它外设提供)
在这里插入图片描述
在这里插入图片描述

EXTI 与 IO对应关系

在这里插入图片描述

STM32 NVIC的使用

在这里插入图片描述

如何使用中断

在这里插入图片描述

STM32 EXTI的配置步骤(外部中断)

在这里插入图片描述

STM32 EXTI的HAL库设置步骤(外部中断)

在这里插入图片描述

HAL库中断回调处理机制介绍

在这里插入图片描述

中断实现编程

通过外部中断控制一个灯亮灭
在这里插入图片描述
exti.h

#ifndef __EXTI_H
#define __EXTI_H#include "./SYSTEM/sys/sys.h"/******************************************************************************************/
/* 引脚 和 中断编号 & 中断服务函数 定义 */ #define KEY0_INT_GPIO_PORT              GPIOE
#define KEY0_INT_GPIO_PIN               GPIO_PIN_4
#define KEY0_INT_GPIO_CLK_ENABLE()      do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0)   /* PE口时钟使能 */
#define KEY0_INT_IRQn                   EXTI4_IRQn
#define KEY0_INT_IRQHandler             EXTI4_IRQHandler#define KEY1_INT_GPIO_PORT              GPIOE
#define KEY1_INT_GPIO_PIN               GPIO_PIN_3
#define KEY1_INT_GPIO_CLK_ENABLE()      do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0)   /* PE口时钟使能 */
#define KEY1_INT_IRQn                   EXTI3_IRQn
#define KEY1_INT_IRQHandler             EXTI3_IRQHandler#define KEY2_INT_GPIO_PORT              GPIOE
#define KEY2_INT_GPIO_PIN               GPIO_PIN_2
#define KEY2_INT_GPIO_CLK_ENABLE()      do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0)   /* PE口时钟使能 */
#define KEY2_INT_IRQn                   EXTI2_IRQn
#define KEY2_INT_IRQHandler             EXTI2_IRQHandler#define WKUP_INT_GPIO_PORT              GPIOA
#define WKUP_INT_GPIO_PIN               GPIO_PIN_0
#define WKUP_INT_GPIO_CLK_ENABLE()      do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)   /* PA口时钟使能 */
#define WKUP_INT_IRQn                   EXTI0_IRQn
#define WKUP_INT_IRQHandler             EXTI0_IRQHandler/******************************************************************************************/void extix_init(void);  /* 外部中断初始化 */#endif

解析:

#define KEY0_INT_IRQHandler  EXTI4_IRQHandler

其中EXTI4_IRQHandler是中断向量表中的中断函数
在这里插入图片描述

exti.c

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/BEEP/beep.h"
#include "./BSP/KEY/key.h"
#include "./BSP/EXTI/exti.h"/*** @brief       KEY0 外部中断服务程序* @param       无* @retval      无*/
void KEY0_INT_IRQHandler(void)
{HAL_GPIO_EXTI_IRQHandler(KEY0_INT_GPIO_PIN);         /* 调用中断处理公用函数 清除KEY0所在中断线 的中断标志位 */__HAL_GPIO_EXTI_CLEAR_IT(KEY0_INT_GPIO_PIN);         /* HAL库默认先清中断再处理回调,退出时再清一次中断,避免按键抖动误触发 */
}/*** @brief       KEY1 外部中断服务程序* @param       无* @retval      无*/
void KEY1_INT_IRQHandler(void)
{ HAL_GPIO_EXTI_IRQHandler(KEY1_INT_GPIO_PIN);         /* 调用中断处理公用函数 清除KEY1所在中断线 的中断标志位,中断下半部在HAL_GPIO_EXTI_Callback执行 */__HAL_GPIO_EXTI_CLEAR_IT(KEY1_INT_GPIO_PIN);         /* HAL库默认先清中断再处理回调,退出时再清一次中断,避免按键抖动误触发 */
}/*** @brief       KEY2 外部中断服务程序* @param       无* @retval      无*/
void KEY2_INT_IRQHandler(void)
{ HAL_GPIO_EXTI_IRQHandler(KEY2_INT_GPIO_PIN);        /* 调用中断处理公用函数 清除KEY2所在中断线 的中断标志位,中断下半部在HAL_GPIO_EXTI_Callback执行 */__HAL_GPIO_EXTI_CLEAR_IT(KEY2_INT_GPIO_PIN);        /* HAL库默认先清中断再处理回调,退出时再清一次中断,避免按键抖动误触发 */
}/*** @brief       WK_UP 外部中断服务程序* @param       无* @retval      无*/
void WKUP_INT_IRQHandler(void)
{ HAL_GPIO_EXTI_IRQHandler(WKUP_INT_GPIO_PIN);        /* 调用中断处理公用函数 清除KEY_UP所在中断线 的中断标志位,中断下半部在HAL_GPIO_EXTI_Callback执行 */__HAL_GPIO_EXTI_CLEAR_IT(WKUP_INT_GPIO_PIN);        /* HAL库默认先清中断再处理回调,退出时再清一次中断,避免按键抖动误触发 */
}/*** @brief       中断服务程序中需要做的事情在HAL库中所有的外部中断服务函数都会调用此函数* @param       GPIO_Pin:中断引脚号* @retval      无*/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{delay_ms(20);      /* 消抖 */switch(GPIO_Pin){case KEY0_INT_GPIO_PIN:if (KEY0 == 0){LED0_TOGGLE();  /* LED0 状态取反 */ LED1_TOGGLE();  /* LED1 状态取反 */ }break;case KEY1_INT_GPIO_PIN:if (KEY1 == 0){LED0_TOGGLE();  /* LED0 状态取反 */ }break;case KEY2_INT_GPIO_PIN:if (KEY2 == 0){LED1_TOGGLE();  /* LED1 状态取反 */ }break;case WKUP_INT_GPIO_PIN:if (WK_UP == 1){BEEP_TOGGLE();  /* 蜂鸣器状态取反 */ }break;}
}/*** @brief       外部中断初始化程序* @param       无* @retval      无*/
void extix_init(void)
{GPIO_InitTypeDef gpio_init_struct;KEY0_GPIO_CLK_ENABLE();                                  /* KEY0时钟使能 */KEY1_GPIO_CLK_ENABLE();                                  /* KEY1时钟使能 */KEY2_GPIO_CLK_ENABLE();                                  /* KEY2时钟使能 */WKUP_GPIO_CLK_ENABLE();                                  /* WKUP时钟使能 */gpio_init_struct.Pin = KEY0_INT_GPIO_PIN;gpio_init_struct.Mode = GPIO_MODE_IT_FALLING;            /* 下升沿触发 */gpio_init_struct.Pull = GPIO_PULLUP;HAL_GPIO_Init(KEY0_INT_GPIO_PORT, &gpio_init_struct);    /* KEY0配置为下降沿触发中断 */gpio_init_struct.Pin = KEY1_INT_GPIO_PIN;gpio_init_struct.Mode = GPIO_MODE_IT_FALLING;            /* 下升沿触发 */gpio_init_struct.Pull = GPIO_PULLUP;HAL_GPIO_Init(KEY1_INT_GPIO_PORT, &gpio_init_struct);    /* KEY1配置为下降沿触发中断 */gpio_init_struct.Pin = KEY2_INT_GPIO_PIN;gpio_init_struct.Mode = GPIO_MODE_IT_FALLING;            /* 下升沿触发 */gpio_init_struct.Pull = GPIO_PULLUP;HAL_GPIO_Init(KEY2_INT_GPIO_PORT, &gpio_init_struct);    /* KEY2配置为下降沿触发中断 */gpio_init_struct.Pin = WKUP_INT_GPIO_PIN;gpio_init_struct.Mode = GPIO_MODE_IT_RISING;             /* 上升沿触发 */gpio_init_struct.Pull = GPIO_PULLDOWN;HAL_GPIO_Init(WKUP_GPIO_PORT, &gpio_init_struct);        /* WKUP配置为下降沿触发中断 */HAL_NVIC_SetPriority(KEY0_INT_IRQn, 0, 2);               /* 抢占0,子优先级2 */HAL_NVIC_EnableIRQ(KEY0_INT_IRQn);                       /* 使能中断线1 */HAL_NVIC_SetPriority(KEY1_INT_IRQn, 1, 2);               /* 抢占1,子优先级2 */HAL_NVIC_EnableIRQ(KEY1_INT_IRQn);                       /* 使能中断线15 */HAL_NVIC_SetPriority(KEY2_INT_IRQn, 2, 2);               /* 抢占2,子优先级2 */HAL_NVIC_EnableIRQ(KEY2_INT_IRQn);                       /* 使能中断线15 */HAL_NVIC_SetPriority(WKUP_INT_IRQn, 3, 2);               /* 抢占3,子优先级2 */HAL_NVIC_EnableIRQ(WKUP_INT_IRQn);                       /* 使能中断线0 */
}

解析

HAL_GPIO_EXTI_IRQHandler(KEY0_INT_GPIO_PIN);

这个函数是在stm32f1xx_hal_gpio.c文件中实现,主要用于清理相应的中断,并调用HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)回调函数,这个回调函数会被重写,在这个回调函数中,根据传入得参数判断是哪个中断,进行相应的操作
在这里插入图片描述
main.c

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/BEEP/beep.h"
#include "./BSP/EXTI/exti.h"int main(void)
{HAL_Init();                            /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9);    /* 设置时钟, 72Mhz */delay_init(72);                        /* 延时初始化 */usart_init(115200);                    /* 串口初始化为115200 */led_init();                            /* 初始化LED */beep_init();                           /* 初始化蜂鸣器 */extix_init();                          /* 初始化外部中断输入 */LED0(0);                               /* 先点亮红灯 */while (1){printf("OK\r\n");delay_ms(1000);}
}
http://www.xdnf.cn/news/5090.html

相关文章:

  • 数据集-目标检测系列- 烟雾 检测数据集 smoke >> DataBall
  • 逐步理解Qt信号与槽机制
  • 【部署满血Deepseek-R1/V3】大型语言模型部署实战:多机多卡DeepSeek-R1配置指南
  • Web3 实战项目项目部署到 GitHub 和上线预览的完整指南
  • django的权限角色管理(RBAC)
  • PyTorch API 4 - 分布式通信、分布式张量
  • 【递归、搜索和回溯】二叉树中的深搜
  • Docker中运行的Chrome崩溃问题解决
  • leetcode-hot-100(哈希)
  • 产品需求分析:需求收集方法(锻造产品内核)
  • 【OpenCV】imread函数的简单分析
  • PyTorch API 8 - 工具集、onnx、option、复数、DDP、量化、分布式 RPC、NeMo
  • 【金仓数据库征文】政府项目数据库迁移:从MySQL 5.7到KingbaseES的蜕变之路
  • STM32-ADC模数转换器(7)
  • 华为云Git使用与GitCode操作指南
  • 湖仓一体架构在金融典型数据分析场景中的实践
  • 多线程 2 - 死锁问题
  • 中国古代史2
  • P1065 [NOIP 2006 提高组] 作业调度方案 详解
  • 【计算机视觉】OpenCV实战项目:Deep Machine Learning Tutors:基于OpenCV的实时面部识别系统深度解析
  • 机器学习第四讲:无监督学习 → 给无标签积木自由组合,发现隐藏规律
  • Lambda表达式解读
  • inotify 文件监控机制
  • C# 参数
  • Kubernetes资源管理之Request与Limit配置黄金法则
  • 《向上生长》读书笔记day5
  • Flutter - UIKit开发相关指南 - 概览
  • 基于语言模型的依存关系分句 和 主题变换检测(基于词频和句段得分)的 意思
  • Git 分支指南
  • socket套接字的超时控制