首页 > 其他分享 >基于STM32F407系列外部中断学习

基于STM32F407系列外部中断学习

时间:2024-11-02 11:49:21浏览次数:5  
标签:优先级 服务 函数 中断 抢占 NVIC 外部 STM32F407

STM32外部中断学习

1)外部中断概述

1.外部中断描述
在日常生活中,例如早上在睡觉被闹钟吵醒,你去关闭闹钟就属于中断事件。
在主函数里的代码是由CPU运行的,CPU在执行过程中突然发生了异常事件(中断),CPU必须暂停当前的工作(设下断点),然后跑去处理这个异常事件的函数(中断服务函数),处理完这个异常事件后(执行完中断服务函数),CPU就会回到刚才的断点,继续执行其它代码。所以主函数和中断服务函数属于同级,互相不能被调用。
中断发生的时间不可知、一旦发生就需要立马去执行
发生的条件:由外部输入数据决定,例如按键输入0/1执行中断服务函数
中断分类:外部中断 软件中断 系统中断

中断示意图

在这里插入图片描述

2)设置中断好处

1.提高硬件的利用率;2.可完善代码的逻辑

举例说明

如寄存器的查询机制

void Usart1_Echo(void)
{
	u8 data;
	while(!(USART1->SR & (1<<5)));
	data=USART1->DR;
	while(!(USART1->SR & (1<<7)));
	USART1->DR=data;
}
	主函数调用了这个函数一直在循环判断标志位,若DR里没有数据到来,一直卡在输入输出的状态位上,不会执行main函数内的剩下的代码。
	如果加入中断服务函数,主函数可一直执行其它代码,把串口数据接收配置为中断,
串口有数据过来 触发断点执行对应的中断服务函数
	中断方式就会大大提升硬件的利用率和完善代码逻辑

3)中断入口及与主函数关系

子函数与主函数

1.主函数可以调用子函数;
2.子函数可以调用子函数 (递归函数)
3.子函数不能调用主函数

中断服务函数与主函数:
中断服务函数与主函数之间不存在调用关系(平级),发生了断点中断服务函数抢占CPU执行中断服务函数、执行完后把CPU还给主函数
执行中断服务函数过程中也有可能触发新的断点

中断嵌套关系图

在这里插入图片描述
如果抢占优先级比当前执行的中断服务函数的优先级更高,可以进行多层嵌套。如果抢占优先级同级,不能进行嵌套。

4)中断优先级说明

中断体系中: 数字越小优先级越高   
优先级别分为:抢占优先级  响应优先级  自然优先级
先比较抢占优先级 抢占一样时才比较响应优先级

在ARM结构下的优先级

ARM体系下的优先级:技术手册第五章(5.3)

在这里插入图片描述

ST公司的ARM体系下进一步封装

ST在ARM体系下中断优先级分组(内核编程手册213页)
在这里插入图片描述
在这里插入图片描述
一定要注意:选择优先级时一定要先选分组号 再写抢占优先级和响应优先级。
一个工程内只能有一个优先级分组!!!否则后续的再次分组会替换掉前面的优先级分组。

5)设置优先级分组函数

函数原型: void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
函数功能:设置优先级分组
形参: PriorityGroup 这个函数的组号按照下图的组号分配

在这里插入图片描述

NVIC_SetPriorityGrouping(1);//1位抢占 3位响应,可以理解为传入的形参就是多少位抢占优先级

6)设置中断优先级函数

函数原型:

void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)

函数功能:设置优先级
形参:
IRQn----中断号
Priority----优先级
例如:

NVIC_SetPriorityGrouping(2);//2位抢占 2位响应
NVIC_SetPriority(USART1_IRQn,6);//串口1的中断设置成抢占优先级为1,响应优先级为2(0110)

NVIC_SetPriorityGrouping(1);//1位抢占 3位响应
NVIC_SetPriority(USART2_IRQn,7);//串口2的中断设置成抢占优先级为0,响应优先级为7(0111)

8)中断使能函数

void __NVIC_EnableIRQ(IRQn_Type IRQn)

传参是中断号

9)3Stm32F4XX中断向量表(参考中文手册或者启动文件stm32f40_41.s)

STM32F4系列有82个中断向量都封装在库函数内,具体可以按CTRL+F搜索IRQn查询需要用到的中断号

10)外部中断使用

GPIO发生电平变化产生的中断(外部中断)
23个中断源(16个EXTI线+7根另外的中断线)—其中16根是IO口触发的
82个IO口 —不可能每个IO口配置中断
相同引脚的IO口公用一个中断—EXTI线
这种公共入口的中断 进入中断服务函数内还需要判断具体哪个中断触发的
在这里插入图片描述
IO口的中断都是由引脚n映射到EXTIn(外部中断线n)上,5-9位共用一个映射,10-15共用一个映射,公用的映射都共用同一个中断服务函数
在这里插入图片描述
所以一个程序内最多只能容纳7+7=14个外部中断服务函数

例如配置PF4引脚的外部中断

首先打开PF时钟和EXTI时钟(SYSCFG时钟)

在数据手册中找到EXTI时钟线对应的SYSCFG时钟

在这里插入图片描述
GPIOF对应的时钟线是AHB1,EXIT(SYSCFG)对应的时钟线是APB2。这里图中标注的EXI时钟线,在参考手册对应是SYSCFG时钟。
在这里插入图片描述
所以我们应该置1该寄存器的第14位
需要配置SYSCFG的寄存器如下
在这里插入图片描述

SYSCFG->EXTICR[1] |=(5<<0);//PF是0101

在这里插入图片描述
这样可以将PF4映射到EXTI4线上

外部中断框图

在这里插入图片描述
从外部中断框图可知,数据通过IO口进来,先经过边沿检测电路(上升沿或下降沿触发),再和中断屏蔽寄存器(置1,开放第EXTIn中断线)进行逻辑与门后,通过挂起寄存器判断第n位数据到来,就可以执行中断服务函数的代码。
在这里插入图片描述
在这里插入图片描述
值得注意是:当发生中断请求,例如PF4中断请求时,
EXTI->PR的第四位会置1,当进入中断服务函数时,对第4位写1可以将标志位清除。
在这里插入图片描述

void system_Config()
{
	RCC->APB2ENR |= (1<<14);//打开外部中断时钟
	RCC->AHB1ENR |= (1<<6);//打开F端口时钟源
	
	SYSCFG->EXTICR[1] |=  (4<<0);   //将PE4引脚映射到EXTI4上
	
	EXTI->RTSR |= (1<<4);//设置为上升沿触发
	EXTI->IMR |= (1<<4);//中断屏蔽寄存器设置
	NVIC_SetPriorityGrouping(2);//设置优先级分组号,2位抢占,2位响应
	NVIC_SetPriority(EXTI4_IRQn, 9);//EXTI0设置抢占2,响应1(1001)
	NVIC_EnableIRQ(EXTI4_IRQn);//使能EXTI4
}

11)同理编写按键中断思路

1.代码中按键能正常工作
2.打开时钟(SYSCFG)
3.配置SYSCFG_EXTICR
4.配置边沿选择寄存器(上升沿 下降沿)
5.使能中断屏蔽寄存器
6.优先级(根据优先级分组,设置n位抢占,4-n位响应,使能中断号)
7.中断服务函数
进服务函数先将标志位写1清零!!

12)中断服务函数的注意事项(重点!)

1.中断服务函数名尽量用复制,不要自己写,因为只要你写错一个字母,这个函数就变成普通函数了。
2.(如果中断服务函数是公共入口)进入到中断服务函数后先要查询是哪种中断
3.先清中断标志,然后再做中断处理,不要把清中断标志放在函数的最后。(如果把清除中断标志放在中断服务函数的最后,会出现当发出清中断标志指令后,硬件还没有把相关标志清除掉,程序就已经跳出了中断服务函数,这个时候NVIC又会识别到标志是1,出现重复中断)。—可以清除中断标志命令发出后,等待清除成功再往下执行。
4.中断服务函数应该尽量简短,一般是做一些标识,不要在中断中做延时之类的占用CPU很长时间的工作。要做到快进快出
5.中断服务函数不会被任何一个函数调用,当中断条件满足后,NVIC控制把CPU拉到中断服务函数中执行。

标签:优先级,服务,函数,中断,抢占,NVIC,外部,STM32F407
From: https://blog.csdn.net/skyllykiki/article/details/143409853

相关文章

  • windows:家庭版 'gpedit.msc' 不是内部或外部命令,也不是可运行的程序
    说明:window10家庭版不支持gpedit.msc命令解决:联网安装所需依赖软件新建bat脚本@echooffsetfileName=policy.txt::获取依赖的软件信息dir/b%systemroot%\servicing\Packages\Microsoft-Windows-GroupPolicy-ClientExtensions-Package~3*.mum>%fileName%dir/b%syste......
  • 通过在 DIM 接入一个外部电容,使得启动时 DIM 端电压缓慢上升,这样 LED 的电流也缓慢上
    AP5165是一款连续电感电流导通模式的降压恒流源,用于驱动一颗或多颗串联LED输入电压范围从6V到30V,输出电流可调,最大可达1.2A。根据不同的输入电压和外部器件,AP5165可以驱动高达数十瓦的LED。AP5165内置功率开关,采用高端电流采样设置LED平均电流,通过DIM引脚可以接受模拟......
  • 以外部表 (External Table) 的形式,接入其他数据源
    外部表|StarRockshttps://docs.starrocks.io/zh/docs/data_source/External_table/外部表StarRocks支持以外部表(ExternalTable)的形式,接入其他数据源。外部表指的是保存在其他数据源中的数据表,而StartRocks只保存表对应的元数据,并直接向外部表所在数据源发起查询。目......
  • 【STM32开发之寄存器版】(十四)-SPI读写外部FLASH
    一、前言STM32F103ZET6内置512KByte的FLASH,当内部FLASH存储器空间不足时,需要通过高速SPI总线外扩FLASH进行读写操作,本文旨在使用STM32F103ZET6自带的SPI实现对外部W25Q128的读写,并将结果显示在TFTLCD模块上。二、SPI基础知识2.1SPI简介SPI是一种高速同步串行输入/输出......
  • AP2813 采用外部供电
    车灯LED高性能双通道输出DC-DC降压恒流芯片AP2813产品描述AP2813是一款双路降压恒流驱动器,高效率、外围简单、内置功率管,适用于5-80V输入的高精度降压LED恒流驱动芯片。内置功率管输出最大功率可达12W,最大电流1.2A。AP2813一路直亮,另外一路通过MODE1切换全亮,爆闪。AP......
  • SpringBoot调用外部接口的几种方式
    使用FeignClient调用FeignClient调用大多用于微服务开发中,各服务之间的接口调用。它以Java接口注解的方式调用HTTP请求,使服务间的调用变得简单1、在使用方引入依赖<!--Feign注解这里openFeign的版本要和自己使用的SpringBoot匹配--><dependency><groupId>org.springfr......
  • 深入探索ReentrantLock(二):解锁中断响应机制
     专栏导航JVM工作原理与实战RabbitMQ入门指南从零开始了解大数据目录前言一、ReentrantLock中断响应机制1.lockInterruptibly()方法讲解2.lockInterruptibly()相比于lock()的优势3.lockInterruptibly()案例总结前言Java并发编程中,ReentrantLock作为可重入互斥......
  • zynq7000 TTC定时器中断
    Note:本次使用pynqz2board作为硬件环境一.Zynq定时器概述在zynq7000中,定时器一共分为4个部分,参考手册:Ug585每颗armA9含有一个私有定时器以及一个看门狗定时器系统含有一个全局看门狗定时器系统含有一个全局定时器系统含有两个TTC模块,每个模块含有三路定时器从......
  • USB协议详解第27讲(USB包-中断传输包详解)
    1.中断传输包结构中断传输和批量传输类似,中断传输只由一个中断事务组成,中断事务包含令牌包、数据包、握手包,如图下所示。中断事务类型的特点是能够通过错误检测和重试来保证主机和设备之间数据的无错误传递。需要理解和注意以下点。(1)当主机准备接收数据时,它发出IN令牌,设备端点......
  • 【项目实战】远程信息处理控制单元(TCU),集成了多种通信技术,如蜂窝网络、Wi-Fi、蓝牙等,使
    一、TCU是什么?TCU,远程信息处理控制单元(TelematicsControlUnit)TCU,是车辆中用于实现远程信息处理功能的关键组件。TCU,集成了多种通信技术,如蜂窝网络、Wi-Fi、蓝牙等,使得车辆能够与外部系统进行数据交换和通信。二、TCU支持的各种应用和服务TCU,在车联网中扮演着重要角色......