完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
概述
中断:中断是指计算机运行过程中,出现某些意外情况需主机干预时,机器能自动停止正在运行的程序并转入处理新情况的程序,处理完毕后又返回原被暂停的程序继续运行 在STM32中(这里以STM32f407为例子),中断共有23条中断线 ●EXTI0-EXTI 15连接到外部中断及GPIO引脚 ● EXTI 线 16 连接到 PVD 输出 ● EXTI 线 17 连接到 RTC 闹钟事件 ● EXTI 线 18 连接到 USB OTG FS 唤醒事件 ● EXTI 线 19 连接到以太网唤醒事件 ● EXTI 线 20 连接到 USB OTG HS(在 FS 中配置)唤醒事件 ● EXTI 线 21 连接到 RTC 入侵和时间戳事件 ● EXTI 线 22 连接到 RTC 唤醒事件 其中外部中断与GPIO口中断相关的16个一一对应相对应每个GPIO组引脚的每一个引脚;即如下图所示,PA组~PI组的0号引脚都连接到同一个EXTI0中断线上,PA组~PI组的所有1号引脚都被连接到同一个EXTI1中断线上,其他中断线以此类推。。。 注意:由于一个中断线上同时连接着多个GPIO的引脚,因此导致一个中断线一个时间内只能设置其中断线上的某一引脚作为它的中断引脚; STM32中CPU处理中断步骤: ①中断触发 ②CPU检测到指定寄存器的标志位为1(下面中断处理函数会讲到) ③CPU跳转预先写好的中断处理函数运行代码 ④运行结束返回原来CPU正在处理的事务进行处理 工程实现 创建工程,需要勾选以下模块 1、开启时钟 如图所示由于中断是在APB2总线上的外设,因此在配置外部中断前需要调用RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);函数用于启动时钟 2、配置GPIO引脚 void _IOInit(void) { //a.使能定时器所需时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); //b.定义用于初始化GPIO引脚的结构体 GPIO_InitTypeDef GPIOa; //c.将用到的外部中断引脚PA0 初始化为输入模式 GPIOa.GPIO_Pin = GPIO_Pin_0; //设置引脚 GPIOa.GPIO_Mode = GPIO_Mode_IN; //设置模式为输入模式 GPIOa.GPIO_Speed = GPIO_Medium_Speed; //这里速度指电平翻转速度中速 GPIOa.GPIO_PuPd = GPIO_PuPd_NOPULL; //无上拉下拉--浮空输入 GPIO_Init(GPIOA,&GPIOa); //初始化 } 3、初始化中断线 这里主要是配置中断线的中断源、模式以及触发的方式等 void _ExtiInit() { //a.初始化中断所使用结构体 EXTI_InitTypeDef extiStruct; //b.将指定的引脚连接到外部中断线上,EXTI0 SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0); //d.初始化外部中断线 extiStruct.EXTI_Line = EXTI_Line0;//启动第0个中断线 EXTI0-EXTI22 extiStruct.EXTI_Mode = EXTI_Mode_Interrupt;//中断模式:中断模式 extiStruct.EXTI_Trigger = EXTI_Trigger_Rising;//触发方式:上升沿触发 extiStruct.EXTI_LineCmd = ENABLE;//使能开启 EXTI_Init(&extiStruct);//初始化中断 } 3、配置外部中断的优先级(嵌套中断向量控制器) void NvicInit() { NVIC_InitTypeDef NvicStruct; NvicStruct.NVIC_IRQChannel = EXTI0_IRQn;//指定中断管理的通道(通过stm32f4xx.h头文件查找IRQn可查找到该表) /* 注意:抢占优先级从0开始(负数的为内核所使用的),0为除内核使用的优先级外最高的抢占优先级, 当同时有两个中断发送至CPU时,会先处理抢占优先级高的中断; 且只有抢占优先级相同的清况下才会去根据响应优先级来判断cpu先处理哪一个中断 */ NvicStruct.NVIC_IRQChannelPreemptionPriority = 2; //设置该中断的抢占优先级(范围0-15) NvicStruct.NVIC_IRQChannelSubPriority = 2; //设置该中断的响应优先级(范围0-15) NvicStruct.NVIC_IRQChannelCmd = ENABLE; //使能 NVIC_Init(&NvicStruct); //初始化 } 值得注意的是,抢占优先级与响应优先级共同所使用的空间只有4bit,可以在main函数开始处调用void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)分组函数(这个函数只能在main函数的开头地方调用,且整个工程只需进行一次分组) NVIC_PriorityGroup:参数范围 0-4 设置0:抢占优先级占0bit,响应优先级占4bit 1:抢占优先级占1bit,响应优先级占3bit 2:抢占优先级占2bit,响应优先级占2bit 3:抢占优先级占3bit,响应优先级占1bit 4:抢占优先级占4bit,响应优先级占0bit 4、中断处理函数 在STM32中中断处理函数是需要使用其官方标准库所提供的中断处理函数名的,且返回值为void空,我们需要去到startup_stm32f40_41xxx.s的一个启动文件中去查找(可能有的放置的位置会不一样); 中断处理函数是当我们配置的中断引脚产生中断后会将中断信号线的中断线标志寄存器的标志位置为1,如中断信号EXTI5产生中断后我们可以使用函数ITStatus EXTI_GetITStatus(uint32_t EXTI_Line)获取指定中断线的标志位是否为1,因此在使用部分中断线是共用一个中断处理函数的,可以在函数中判断中断信号线的标志位是否被置为1了;注意:每次中断处理完以后需要使用函数void EXTI_ClearITPendingBit(uint32_t EXTI_Line)把中断的标志位清除,否则会一直重复地进入中断处理函数 使用单个中断线的中断函数: void EXTI3_IRQHandler() { /*.。。想要中断处理的代码。。.*/ //将中断标志位清为0 EXTI_ClearITPendingBit(EXTI_Line3); } 在多个中断线一起使用的中断处理函数中,可如代码所示判断其中断线寄存器标志位进行判断当前触发的中断来自哪一条中断线 void EXTI9_5_IRQHandler(void) { //先判断 EXTi5 EXTI6的哪个标志位置为1 if(EXTI_GetITStatus(EXTI_Line5) == 1) { //能进来这里表示是EXTI5触发的中断 EXTI_ClearITPendingBit(EXTI_Line5); } if(EXTI_GetITStatus(EXTI_Line6) == 1) { //能进来这里表示是EXTI6触发的中断 EXTI_ClearITPendingBit(EXTI_Line6); } } 这是个人在对STM32学习中断时对于中断的理解,若有错误的地方敬请见谅并麻烦大佬们纠正一下。非常感谢 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1602 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1536 浏览 1 评论
967 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
680 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1579 浏览 2 评论
1861浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
642浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
514浏览 3评论
528浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
501浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-19 19:36 , Processed in 0.636468 second(s), Total 79, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号