完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
概念与介绍
STM32F7 的每个 IO 都可以作为外部中断的中断输入口,STM32F7 的中断控制器支持 22 个外部中断/事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。STM32F7的 23 个外部中断为: [tr]端口对应中断[/tr]
GPIO的引脚 GPIOx.0~GPIOx.15(x=A,B,C,D,E,F,G,H,I)分别对应中断线 0~15。这样每个中断线对应了最多 9 个 IO 口,以线 0 为例:它对应了 GPIOA.0、GPIOB.0、GPIOC.0、GPIOD.0、GPIOE.0、GPIOF.0、GPIOG.0,GPIOH.0,GPIOI.0。 而中断线每次只能连接到 1 个 IO 口上,这样就需要通过配置来决定对应的中断线配置到哪个 GPIO 上了。GPIO 和中断线映射关系是在寄存器 SYSCFG_EXTICR1~ SYSCFG_EXTICR4 中配置的。 使用的介绍 因为STM32的中断非常多,所以必须设置中断的优先级,设置完优先级之后编写中断服务函数,进行中断服务函数的挂载。 中断的使用基本流程为 1)使能 IO 口时钟。 2)调用函数 HAL_GPIO_Init 设置 IO 口模式,触发条件,使能 SYSCFG 时钟以及设置 IO 口与中断线的映射关系。 3)配置中断优先级(NVIC),并使能中断。 4)在中断服务函数中调用外部中断共用入口函数 HAL_GPIO_EXTI_IRQHandler。 5)编写外部中断回调函数 HAL_GPIO_EXTI_Callback 实现控制逻辑。 下文为过程详细介绍 使能IO时钟&基本配置 首先,我们要使用 IO 口作为中断输入,所以我们要使能相应的 IO 口时钟,之后 设置 IO 口模式,触发条件,开启 SYSCFG 时钟,设置 IO 口与中断线的映射关系 __HAL_RCC_GPIOA_CLK_ENABLE(); //开启 GPIOA 时钟 GPIO_InitTypeDef GPIO_Initure; GPIO_Initure.Pin=GPIO_PIN_0; //PA0 GPIO_Initure.Mode=GPIO_MODE_IT_RISING; //外部中断,上升沿触发 GPIO_Initure.Pull=GPIO_PULLDOWN; //默认下拉 HAL_GPIO_Init(GPIOA,&GPIO_Initure); 之后设置中断优先级 设置中断优先级(NVIC) HAL_NVIC_SetPriority(EXTI0_IRQn,2,1); //抢占优先级为 2,子优先级为 1 HAL_NVIC_EnableIRQ(EXTI0_IRQn); //使能中断线 2 中断服务函数 们配置完中断优先级之后,接着要做的就是编写中断服务函数。中断服务函数的名字是 在 HAL 库中事先有定义的。有 7 个,分别为: void EXTI0_IRQHandler(); void EXTI1_IRQHandler(); void EXTI2_IRQHandler(); void EXTI3_IRQHandler(); void EXTI4_IRQHandler(); void EXTI9_5_IRQHandler(); void EXTI15_10_IRQHandler(); 中断线 0-4 每个中断线对应一个中断函数,中断线 5-9 共用中断函数EXTI9_5_IRQHandler,中断线 10-15 共用中断函数 EXTI15_10_IRQHandler。一般情况下,我们可以把中断控制逻辑直接编写在中断服务函数中,但是 HAL 库把中断处理过程进行了简单封装,也就是中断处理的回调函数。 //使用如下 //中断服务函数 void EXTI0_IRQHandler(void) { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0); //调用中断处理公用函数 } 编写中断处理的回调函数HAL_GPIO_EXTI_Callback 在使用 HAL 库的时候,我们也可以跟使用标准库一样,在中断服务函数中编写控制逻辑。但 是 HAL 库 为 了 用 户 使 用 方 便 , 它 提 供 了 一 个 中 断 通 用 入 口 函 数HAL_GPIO_EXTI_IRQHandler,在该函数内部直接调用回调函数HAL_GPIO_EXTI_Callback。 HAL_GPIO_EXTI_IRQHandler 函数定义: void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin) { if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET) { __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin); HAL_GPIO_EXTI_Callback(GPIO_Pin); } } 该函数实现的作用非常简单,通过入口参数 GPIO_Pin 判断中断来自哪个 IO 口,然后清除相应的中断标志位,最后调用回调函数 HAL_GPIO_EXTI_Callback()实现控制逻辑。所以我们编写中断控制逻辑将跟串口实验类似,在所有的外部中断服务函数中直接调用外部中断共用处理函数 HAL_GPIO_EXTI_IRQHandler,然后在回调函数HAL_GPIO_EXTI_Callback 中通过判断中断是来自哪个 IO 口编写相应的中断服务控制逻辑。 相关概念 事件、中断事件、中断 事件、中断事件 中断三个概念或术语。这三个概念彼此关联,有时会让人有点混淆或犯迷糊。 拿一件生活中的事情打比方对上述三个概念做个基本的粗略理解,比如一老师在教室里给学生们上课。课堂上的学生可能做出各种行为动作,比方做笔记、打哈气、翻书包、讲小话等,我们把这些行为统称为事件,其中有些行为老师往往只是视而不见,继续他的上课;而有些行为可能导致老师的上课中止,比方讲小话,并对学生的相关行为予以警告、批评或纠正等,然后继续上课。我们把老师因为学生的某些行为而中止授课,并产生后续动作,之后接着上课的这个过程理解为中断或中断响应。我们把可能导致老师上课中断的学生行为理解为中断事件。 结合上面的比方,不难理解中断事件是一种可以导致中断发生的事件,中断则是因为中断事件的发生而导致的后续行为过程。事件与中断事件是包含关系,即事件可分为中断事件或非中断事件。而中断事件与中断之间属于前后关联的因果关系,虽有关联,但二者在时序上、行为上并不一样。 中断服务函数使用的注意事项 中断服务函数名是固定的,在启动代码里面已经定下来了。 书写中断服务函数的时候注意的问题:
程序代码 //本程序是通过外部中断实现,四个按键按下从而控制LED灯呈现不同效果的程序 #include "exti.h" #include "delay.h" #include "led.h" #include "key.h" //中断初始化 void EXTI_Init(void) { GPIO_InitTypeDef GPIO_Initure; //几个按键相关的时钟 __HAL_RCC_GPIOA_CLK_ENABLE(); //开启时钟GPIOA __HAL_RCC_GPIOC_CLK_ENABLE(); //开启时钟GPIOC __HAL_RCC_GPIOH_CLK_ENABLE(); //开启时钟GPIOH GPIO_Initure.Pin=GPIO_PIN_0; //PA0 GPIO_Initure.Mode=GPIO_MODE_IT_RISING; //上升沿触发 GPIO_Initure.Pull=GPIO_PULLDOWN; //下拉 HAL_GPIO_Init(GPIOA,&GPIO_Initure); GPIO_Initure.Pin=GPIO_PIN_13; //PC13 GPIO_Initure.Mode=GPIO_MODE_IT_FALLING; //下降沿触发 GPIO_Initure.Pull=GPIO_PULLUP; //上拉 HAL_GPIO_Init(GPIOC,&GPIO_Initure); GPIO_Initure.Pin=GPIO_PIN_2|GPIO_PIN_3; //PH2,3 下降沿触发,上拉 HAL_GPIO_Init(GPIOH,&GPIO_Initure); //中断线0优先级设置 HAL_NVIC_SetPriority(EXTI0_IRQn,2,0); //优先级为2,子优先级为1 HAL_NVIC_EnableIRQ(EXTI0_IRQn); //使能中断线0 //中断线2优先级设置 HAL_NVIC_SetPriority(EXTI2_IRQn,2,1); HAL_NVIC_EnableIRQ(EXTI2_IRQn); //中断线3优先级设置 HAL_NVIC_SetPriority(EXTI3_IRQn,2,2); HAL_NVIC_EnableIRQ(EXTI3_IRQn); //中断线13优先级设置 HAL_NVIC_SetPriority(EXTI15_10_IRQn,2,3); HAL_NVIC_EnableIRQ(EXTI15_10_IRQn); } //中断服务函数 void EXTI0_IRQHandler(void) { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0); //调用中断公用处理函数 } void EXTI2_IRQHandler(void) { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2); //调用中断公用处理函数 } void EXTI3_IRQHandler(void) { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_3); //调用中断公用处理函数 } void EXTI15_10_IRQHandler(void) { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13); //调用中断公用处理函数 } //中断处理公用函数的回调函数 //中断处理公用函数在stm32f7xx_hal_gpio.c中定义,并且调用HAL_GPIO_EXTI_Callback(GPIO_Pin); //在hal库中所有外部中断服务函数都会调用此函数 //Pram:GPIO_Pin-中断引脚 void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { static u8 led0sta=1,led1sta=1; delay_ms(50); //消抖 switch(GPIO_Pin) { case GPIO_PIN_0: if(WK_UP==1) //控制LED0 LED1 互斥点亮 { led1sta=!led1sta; led0sta=!led1sta; LED1(led1sta); LED0(led0sta); } break; case GPIO_PIN_2: if(KEY1==0) //同时控制 LED1 { led1sta=!led1sta; LED1(led1sta); }; break; case GPIO_PIN_3: if(KEY0==0) //同时控制LED0 LED1 { led1sta=!led1sta; led0sta=!led0sta; LED1(led1sta); LED0(led0sta); } break; case GPIO_PIN_13: if(KEY2==0) //LED0翻转 { led0sta=!led0sta; LED0(led0sta); } break; } } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1646 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1566 浏览 1 评论
993 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
692 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1611 浏览 2 评论
1871浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
656浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
526浏览 3评论
543浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
515浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-27 07:20 , Processed in 0.737822 second(s), Total 76, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号