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

STM32_08_中断(☆☆☆)

中断介绍

中断和轮询

中断的硬件连接

EXTI0

  • 类似这种梯形就是多选一,例如PB1这个引脚的电平变化会映射到EXTI1硬联。
  • STM32 通过SYSCFG(或 F1 系列的 AFIO)的 EXTICR 配置寄存器,将特定 GPIO 引脚(如 PA0、PB1 等)“绑定” 到对应的 EXTI 中断线(EXTIn);当该引脚发生电平变化(上升沿、下降沿等)时,就会触发对应 EXTI 线,进而产生中断请求或事件信号。
  • 通过AFIO_EXTICRx配置GPIO线上的外部中断/事件,而如果想让GPIO线映射过来,首先要使能AFIO时钟

  1. GPIO变化过程映射到EXTI线上
    打开AFIO时钟
  2. EXTI控制器内部
    上升沿/下降沿
    中断/事件
    清除中断到来位
    使能中断 - 不能屏蔽

NVIC介绍

NVIC中断优先级

速记:抢占式优先级是主优先级,响应优先级是子优先级。

  1. 中断A:主1子0
    中断B:主0子2    
    -> 同时到 -> B
  2. 中断A:主1子0
    中断B:主0子2    
    -> A先到,执行, B到了 -> B会抢占A的资源
  3. 中断A:主1子0
    中断B:主1子2    
    -> 同时到 -> A先执行
  4. 中断A:主1子0
    中断B:主1子2    
    -> B先到, 执行, A到了 -> A不会抢占B的资源  
  5. 中断A:主1子2
    中断B:主1子2    
    -> 同时到 -> 看表(谁在前谁先运行)

4bit:
主4子0
主:0-15子:                                        ( < 2的n次方)
主3子1
主:0-7子:0-1
主2子2
主:0-3子:0-3
主1子3
主:0-1子:0-7

主0子4
主: 子:0-15

外部EXTI配置

中断处理

思考:

PA0 - EXTI0 - EXTI - NVIC - CPU  
谁触发的中断?
EXTI0触发的中断 ,并不是PA0,是PA0映射到了EXTI0,EXTI0一步步触发的中断。

stm32 - 中断处理函数 - 名字定好了  - 启动文件中
打开启动文件: XXX_IRQHandler 
EXTI0_IRQHandler 
1.中断处理函数
2.EXIT0触发的中断调用该函数 
中断处理函数没有定义, 需要开发人员自定义 

中断处理流程

中断处理函数

1.APP/EXTI目录 
2.APP/EXTI
新建exti.c exti.h 
3.添加工程组/ C/C++头文件路径 
4.工程组添加 stm32f10x_exti.c - EXTI库函数 

KEY0按键

相关库函数和结构体

代码示例:

KEY0按键

思路:

KEY0一旦按下,GPIOE4就映射到了EXTI4上,然后会有一个下降沿,EXTI4设置中断模式,又能检测下降沿,然后发送一个中断信号到NVIC,NVIC发现是EXTI4的中断,给你分配了一个主优先级和子优先级,然后NVIC把中断信号发送到CPU里。

相关库函数和结构体

代码示例:

注意:

EXTI和NVIC有时钟,但是它们自动使能。IRQn在stm32f10x.h头文件的第167行,下面就是各个中断源。

xxxx_IRQn - 中断源 - 谁触发的中断 - 
NVIC_InitTypeDef - IRQChannel - 赋值 

接下来调用中断处理函数

实战演练

代码示例:

exti.h:

// exti.h
#ifndef __EXTI_H__
#define __EXTI_H__#include "stm32f10x.h"// KEY0
extern void My_EXTI_Init(void);
#endif

exti.c:

// exti.c
#include "exti.h"
#include "systick.h"
#include "beep.h"
#include "key.h"
// 
// 中断的初始化 - 发送中断的流程
// KEY0 - GPIOE4
// KEY0 - GPIOE4 - EXTI4 - EXTI控制器 - NVIC - CPU核
//
void My_EXTI_Init(void){// 1.KEY0 - 配置为上拉输入// 2.GPIOE4映射到EXTI4上// 2.1打开AFIO时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);// 2.2将GPIOE3映射到EXTI4上GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource4);// 3.EXTI控制器的配置// EXTI4 - 中断模式 - 下降沿触发EXTI_InitTypeDef EXTI_Config;EXTI_Config.EXTI_Line = EXTI_Line4;							 // EXTI4EXTI_Config.EXTI_Mode = EXTI_Mode_Interrupt;		 // 中断模式EXTI_Config.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿EXTI_Config.EXTI_LineCmd = ENABLE;							 // 使能EXTI_Init(&EXTI_Config);// 4.NVIC控制器的配置// EXTI4触发的中断 - 主1 - 子2 - 使能NVIC_InitTypeDef NVIC_Config; NVIC_Config.NVIC_IRQChannel = EXTI4_IRQn; // EXTI4触发的中断NVIC_Config.NVIC_IRQChannelPreemptionPriority = 1;NVIC_Config.NVIC_IRQChannelSubPriority = 2;NVIC_Config.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_Config);
}
//
// 中断处理函数到启动文件(.s)中找
// 中断处理函数
// 触发该函数 - KEY0按下 - 蜂鸣器控制
//
void EXTI4_IRQHandler(void){// 判断是否是EXTI4触发的中断if(EXTI_GetITStatus(EXTI_Line4) == SET){// 业务处理delay_ms(10); // 去抖动if(KEY0 == 0)BEEP = !BEEP;}// 清除中断到来位EXTI_ClearITPendingBit(EXTI_Line4);
}

main.c:

// main.c 
#include "stm32f10x.h"
#include "led.h"
#include "beep.h"
#include "system.h"
#include "systick.h"
#include "key.h"
#include "exti.h"int main(void)
{// |--|--|NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// LED初始化 LED_Init();// BEEP初始化 BEEP_Init();// systick初始化 Systick_Init();// KEY初始化KEY_Init();// EXTI初始化// 作用:按下KEY0 - EXTI4 - EXTI -NVIC -> 中断信号 -> CPU核My_EXTI_Init();while(1){// 业务逻辑 - 做其他事情LED1 = !LED1;delay_ms(1000);}// 启动文件 - main函数 - 初始化 - while(1)// while(1) -------(1)-----------------> 执行//								 ^CPU核// 								/// 按下KEY0->中断信号//										CPU核从(1)停止 -> 执行中断处理函数//																		EXTI4_IRQHandler//																    执行完返回(1)继续
}

补充:

  1. 和中断相关的三类函数:
    xxx_ITConfig            - 打开/关闭控制器的某个中断
    xxx_GetITStatus         - 判断某个中断是否到来
    xxx_ClearITPendingBit   - 中断中断到来位
  2. EXTI_GetITStatus(EXTI_Line4) == SET的作用
    例如:
    EXTI6触发了中断, 调用其中断处理函数
    // EXTI5 6 7 8 9 触发的中断调用该函数
    // 问 - 是哪个硬件线触发的中断调用的该函数 
    void EXTI9_5_IRQHandler(void){
    if(EXTI_GetITStatus(EXTI_Line5) == SET){...}
    else if(EXTI_GetITStatus(EXTI_Line6) == SET){...}
    else if(EXTI_GetITStatus(EXTI_Line7) == SET){...}
    else if(EXTI_GetITStatus(EXTI_Line8) == SET){...}
    else if(EXTI_GetITStatus(EXTI_Line9) == SET){...}
    }

拓展:

循环开关灯,按下key0触发中断,开启蜂鸣器;按下key_up触发中断,关闭蜂鸣器。

KEY_UP使用中断来触发:
PA0 - 下拉输入 
低电平 - 高电平 - 低电平 
检测 - 上升沿 
谁触发的中断 - EXTI0  

初始化函数:
1.PA0 映射到EXTI0 
2.EXTI配置 - EXTI0, 中断模式, 上升沿, 使能 
3.NVIC配置 - EXTI0, 主1, 子0, 使能 

中断处理函数:
EXTI0_IRQHandler

exti.c:

// exti.c
#include "exti.h"
#include "systick.h"
#include "beep.h"
#include "key.h"
// 
// 中断的初始化 - 发送中断的流程
// KEY0 - GPIOE4
// KEY0 - GPIOE4 - EXTI4 - EXTI控制器 - NVIC - CPU核
// KEY_UP - GPIOA0 - EXTI0 - EXTI控制器 - NVIC - CPU核
//
void My_EXTI_Init(void){// 1.KEY0 - 配置为上拉输入// 1.2KEY_UP配置为下拉输入// 2.GPIOE4映射到EXTI4上// 2.1打开AFIO时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);// 2.2将GPIOE3映射到EXTI4上GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource4);// 2.2将GPIOA0映射到EXTI0上GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);// 3.EXTI控制器的配置// EXTI4 - 中断模式 - 下降沿触发EXTI_InitTypeDef EXTI_Config;EXTI_Config.EXTI_Line = EXTI_Line4;							 // EXTI4EXTI_Config.EXTI_Mode = EXTI_Mode_Interrupt;		 // 中断模式EXTI_Config.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿EXTI_Config.EXTI_LineCmd = ENABLE;							 // 使能EXTI_Init(&EXTI_Config);// 3.2EXTI0 - 中断模式 - 上升沿触发EXTI_Config.EXTI_Line = EXTI_Line0;EXTI_Config.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_Config.EXTI_Trigger = EXTI_Trigger_Rising;EXTI_Config.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_Config);// 4.NVIC控制器的配置// EXTI4触发的中断 - 主1 - 子2 - 使能NVIC_InitTypeDef NVIC_Config; NVIC_Config.NVIC_IRQChannel = EXTI4_IRQn; // EXTI4触发的中断NVIC_Config.NVIC_IRQChannelPreemptionPriority = 1;NVIC_Config.NVIC_IRQChannelSubPriority = 2;NVIC_Config.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_Config);// 4.2EXTI0触发的中断 - 主1 - 子0 - 使能NVIC_Config.NVIC_IRQChannel = EXTI0_IRQn;NVIC_Config.NVIC_IRQChannelPreemptionPriority = 1;NVIC_Config.NVIC_IRQChannelSubPriority = 0;NVIC_Config.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_Config);
}
//
// 中断处理函数到启动文件(.s)中找
// 中断处理函数
// 触发该函数 - KEY0按下 - 蜂鸣器控制
//
void EXTI4_IRQHandler(void){// 判断是否是EXTI4触发的中断if(EXTI_GetITStatus(EXTI_Line4) == SET){// 业务处理delay_ms(10); // 去抖动if(KEY0 == 0)BEEP = 1;}// 清除中断到来位EXTI_ClearITPendingBit(EXTI_Line4);
}void EXTI0_IRQHandler(void){// 判断是否是EXTI0触发的中断if(EXTI_GetITStatus(EXTI_Line0) == SET){// 业务处理delay_ms(10);if(KEY_UP == 1)BEEP = 0;}// 清除中断到来位EXTI_ClearITPendingBit(EXTI_Line0);
}

main.c:

// main.c 
#include "stm32f10x.h"
#include "led.h"
#include "beep.h"
#include "system.h"
#include "systick.h"
#include "key.h"
#include "exti.h"int main(void)
{// |--|--|NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// |--|--|NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);// LED初始化 LED_Init();// BEEP初始化 BEEP_Init();// systick初始化 Systick_Init();// KEY初始化KEY_Init();// EXTI初始化// 作用:按下KEY0 - EXTI4 - EXTI -NVIC -> 中断信号 -> CPU核My_EXTI_Init();while(1){// 业务逻辑 - 做其他事情LED1 = !LED1;delay_ms(1000);}// 启动文件 - main函数 - 初始化 - while(1)// while(1) -------(1)-----------------> 执行//								 ^CPU核// 								/// 按下KEY0->中断信号//										CPU核从(1)停止 -> 执行中断处理函数//																		EXTI4_IRQHandler//																    执行完返回(1)继续
}

http://www.dtcms.com/a/399454.html

相关文章:

  • 网站建设合优wordpress首页添加视频
  • todesk开启虚拟屏后被控黑屏
  • 学校网站建设的申请书推广100种方式
  • 瑞芯微RK3506核心板/开发板DSM音频开发实战,关键知识点与实操案例必看攻略!
  • 网站建设项目明细表网站建设讠金手指科杰
  • 美文的手机网站代理服务器地址怎么找
  • 自动化单mysql多实例库的全量迁移脚本
  • Lucene 8.7.0 版本中doc、tim、tip、tmd文件详解
  • golang1.18升级到1.23遇到的坑
  • 网站建设广告费 科目高埗网站仿做
  • 52Hz——FreeRTOS学习笔记——FReeRTOS移植遇到的问题
  • 网站建设肆金手指排名7全网通网站
  • AI赋能互联网广告变现的商业模式
  • 52Hz——FreeRTOS学习笔记——删除任务
  • AI 重塑教育生态:从个性化学习到公平鸿沟
  • 将二级域名 网站目录网站首页排名下降
  • 实现Word文档自动编号提取技术详解
  • 超越OCR:深入智能文档处理(IDP)的技术内核与实现路径
  • 江苏自助建站平台html5游戏开发
  • SQL server 2022下载安装详细教程
  • 工业视觉缺陷检测算法总结:从传统到深度学习,5类核心算法
  • 建设银行网站打不开别的网站可以口碑好的移动网站建设
  • 网站怎么建设原始站点定制网站的好处有哪些
  • 推动商用车辆原始设备制造商(OEM)向集中式电子电气架构(E/E,Electrical/Electronic)与软件架构转型
  • 网站内页模板玉溪市住房城乡建设局网站
  • Navicat 数据库管理工具简介​以及免费绿色版下载安装包分享 不登录csdn也可以直接使用
  • 第二章:Qt第一个程序
  • APache shiro-550 CVE-2016-4437复现
  • 计算机视觉笔试选择题:题组2
  • 荣耀手机商城官方网站入口唐山网页设计