STM32F4xxNVIC与EXTI中断(HAL库)

更新时间:2023-06-24 19:06:17 阅读: 评论:0

bulkSTM32F4xxNVIC与EXTI中断(HAL库)失败者英语
⽂章⽬录
概述
 使⽤STM32F407的EXTI中断功能需要使⽤HAL库中的stm32f4xx_hal_exti.h和stm32f4xx_
 STM32F4的每个GPIO都可设置为EXTI中断功能。STM32F4有16路EXTI中断线EXTI0~EXTI15,所有GPIOx的GPIO_PIN_0对应EXTI0,所有GPIOx的GPIO_PIN_1对应EXTI1 … 所有GPIOx的GPIO_PIN_15对应EXTI15.
NVIC配置
 关于NVIC中断管理的函数定义在stm32f4xx_hal_cortex.c中。
推荐信留学中断优先级分组
/* 设置全局中断优先级分组,此函数只需调⽤⼀次
参数:
NVIC_PRIORITYGROUP_0
NVIC_PRIORITYGROUP_1
NVIC_PRIORITYGROUP_2
NVIC_PRIORITYGROUP_3
NVIC_PRIORITYGROUP_4 */
void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup);
PriorityGroup PreemptPriority SubPriority NVIC_PRIORITYGROUP_0none0~15
dbmNVIC_PRIORITYGROUP_10~10~7
NVIC_PRIORITYGROUP_20~30~3
NVIC_PRIORITYGROUP_30~70~1
NVIC_PRIORITYGROUP_40~15none
设置中断优先级
/* 设置指定中断事件的抢占优先级和响应优先级
参数:
(IRQ_Type)IRQn - 中断名
(uint32_t)PreemptPriority - 抢占优先级
(uint32_t)SubPriority - 响应优先级 */
void HAL_NVIC_SetPriority(IRQn_Type IRQn,uint32_t PreemptPriority,uint32_t SubPriority);
使能中断
/* 开启指定中断 */
void HAL_NVIC_EnableIRQ(IRQn_Type IRQn);
/* 关闭指定中断 */
void HAL_NVIC_DisableIRQ(IRQn_Type IRQn);
抢占优先级和响应优先级
 STM32单⽚机的优先级有两个属性:抢占优先级和响应优先级(⼜称⼦优先级),优先级编号越⼩其优先级越⾼。
 抢占优先级(PreemptPriority):⾼抢占优先级的中断程序可以打断低抢占优先级的中断程序。即如果低抢占优先级的中断程序正在运⾏,此时发⽣⾼抢占优先级的中断事件,⾼抢占优先级的中断程序可以打断正在运⾏的低抢占优先级程序。
 响应优先级(SubPriority):当抢占优先级相同时,⾼响应优先级的中断程序先于低响应优先级的中断程序执⾏。响应优先级只能处理同时发⽣的中断事件,⽽不能打断正在处理的中断事件。
 如果两个中断事件的抢占优先级和响应优先级都相同,先发⽣的中断事件先被处理。
 总结:抢占优先级(PreemptPriority)⽤于管理中断事件的处理权,未开始执⾏的中断程序(⾼抢占优先级)可以抢占正在执⾏的中断程序(低抢占优先级)的执⾏权。响应优先级(SubPriority)⽤于管理同时发⽣的中断事件的处理顺序,未开始执⾏的中断程序不能打断正在执⾏的中断程序。
GPIO配置
GPIO初始化
GPIO_InitTypeDef GPIO_Init;
五年级上册英语试卷/* GPIOx时钟初始化。注意,IO中断仅需初始化对应GPIO的时钟即可 */
__HAL_RCC_GPIOx_CLK_ENABLE();
GPIO_Init.Pin = GPIO_PIN_0;
/* GPIO_MODE_IT_RISING (外部事件,上升沿触发);
GPIO_MODE_IT_FALLING (外部事件,下降沿触发);
GPIO_MODE_IT_RISING_FALLING (外部事件,上升沿或下降沿触发). */
// 上升沿触发
GPIO_Init.Mode = GPIO_MODE_IT_RISING;
// 上升沿触发,可选择下拉或者⽆拉
GPIO_Init.Pull = GPIO_PULLDOWN;
GPIO_Init.Speed = GPIO_SPEED_HIGH;
HAL_GPIO_Init(GPIOC,&GPIO_Init);
EXTI中断事件名
濡れた髪を初めて见せてくれた君typedef enum{
...
EXTI0_IRQn =6,//IO中断事件0, 对应 GPIOx 的 GPIO_PIN_0
EXTI1_IRQn =7,//IO中断事件1, 对应 GPIOx 的 GPIO_PIN_1
EXTI2_IRQn =8,//IO中断事件2, 对应 GPIOx 的 GPIO_PIN_2
EXTI3_IRQn =9,//IO中断事件3, 对应 GPIOx 的 GPIO_PIN_3
EXTI4_IRQn =10,//IO中断事件4, 对应 GPIOx 的 GPIO_PIN_4
EXTI9_5_IRQn =23,//IO中断事件5~9, 对应 GPIOx 的 GPIO_PIN_5 ~ GPIO_PIN_9totalamount
EXTI15_10_IRQn =40,//IO中断事件10~15, 对应 GPIOx 的 GPIO_PIN_10 ~ GPIO_PIN_15
...
} IRQn_Type
⽰例:
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_1);
HAL_NVIC_SetPriority(EXTI0_IRQn,0,0);
HAL_NVIC_EnableIRQ(EXTI0_IRQn);
判断触发中断的GPIO_Pin
 对于GPIO_PIN_5 ~ GPIO_PIN_9和GPIO_PIN_10 ~ GPIO_PIN_15,中断服务函数仅有EXTI9_5_IRQHandler()和EXTI15_10_IRQHandler(),发⽣中断时,不能直接得到触发中断的GPIO,需要借助具体函数判断:
/* 判断指定的GPIO_Pin是否触发了EXTI中断。
参数:GPIO_Pin - 指定的GPIO_Pin
返回:
(ITStatus)SET - 指定的GPIO_Pin触发了EXTI中断
(ITStatus)RESET - 指定的GPIO_Pin未触发EXTI中断
*/
ITStatus __HAL_GPIO_EXTI_GET_IT(uint16_t GPIO_Pin);
⽰例:
void EXTI9_5_IRQHandler(void){
uint16_t GPIO_Pin;
// Get the GPIO_Pin which requsted EXTI handle
if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_5)!= RESET){
GPIO_Pin = GPIO_PIN_5;
}el if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_6)!= RESET){  GPIO_Pin = GPIO_PIN_6;
}el if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_7)!= RESET){  GPIO_Pin = GPIO_PIN_7;
}el if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_8)!= RESET){  GPIO_Pin = GPIO_PIN_8;
}el if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_9)!= RESET){  GPIO_Pin = GPIO_PIN_9;
}
HAL_GPIO_EXTI_IRQHandler(GPIO_Pin);
}
void EXTI15_10_IRQHandler(void){
uint16_t GPIO_Pin;
/
/ Get the GPIO_Pin which requsted EXTI handle
if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_10)!= RESET){
GPIO_Pin = GPIO_PIN_10;
}el if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_11)!= RESET){  GPIO_Pin = GPIO_PIN_11;
}el if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_12)!= RESET){  GPIO_Pin = GPIO_PIN_12;
}el if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_13)!= RESET){  GPIO_Pin = GPIO_PIN_13;
}el if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_14)!= RESET){  GPIO_Pin = GPIO_PIN_14;
}el if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_15)!= RESET){  GPIO_Pin = GPIO_PIN_15;
}
HAL_GPIO_EXTI_IRQHandler(GPIO_Pin);
}
中断服务函数
/* EXTI0_IRQn */
void EXTI0_IRQHandler(void){}
/* EXTI1_IRQn */
void EXTI1_IRQHandler(void){}
/* EXTI2_IRQn */
void EXTI2_IRQHandler(void){}
/* EXTI3_IRQn */
void EXTI3_IRQHandler(void){}
/* EXTI4_IRQn */
void EXTI4_IRQHandler(void){}
/
* EXTI5_IRQn~EXTI9_IRQn */
void EXTI9_5_IRQHandler(void){}
/* EXTI10_IRQn~EXTI15_IRQn */
void EXTI15_10_IRQHandler(void){}
中断回调函数
概述
 使⽤中断服务函数处理中断事件时,需要在中断服务函数中⼿动清除中断标志。HAL库提供了更为简洁的中断处理⽅式:通⽤⼊⼝函数+中断回调函数。
通⽤⼊⼝函数
 通⽤⼊⼝函数HAL_GPIO_EXTI_IRQHandler()定义在stm32f4xx_hal_gpio.c中。
/* 通⽤⼊⼝函数的组成:
1.清除中断标志:__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
2.中断处理逻辑:HAL_GPIO_EXTI_Callback(GPIO_Pin); */
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);
}
}
 通⽤⼊⼝函数的⽬的是封装中断标志的清除处理。直接在中断服务函数中调⽤通⽤⼊⼝函数即可,传⼊对应的参数,不必⼿动清除中断标志。例:
void EXTI0_IRQHandler(void){
// 调⽤通⽤⼊⼝函数
HAL_GPIO_EXTI_IRQHandler(GOIO_PIN_0);
第57届格莱美
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
// 中断处理逻辑
}
中断回调函数
 中断回调函数HAL_GPIO_EXTI_Callback()定义在stm32f4xx_hal_gpio.c中。中断回调函数实现中断处理逻辑,被通⽤⼊⼝函数调⽤。只需正确声明定义中断回调函数,⽽⽆需显式调⽤。
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
// 中断处理逻辑
}
总结
 使⽤HAL库实现EXTI中断的函数调⽤流程为:
/* 中断向量函数,在中断向量函数中调⽤
__HAL_GPIO_EXTI_GET_IT(GPIO_Pin)判断指定的GPIO_Pin是否触发中断 */ 1.void EXTIx_IRQHandler(void);
/* 通⽤⼊⼝函数,清除中断标志,被 HAL_GPIO_EXTI_Callback() 调⽤ */
2.void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin);
/* 中断回调函数,⽤户定义中断处理逻辑 */
3.void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);
⽰例
main.c
#include"stm32f4xx.h"
/* define */
#define LED_Port GPIOC
#define LED_Pin GPIO_PIN_0
#define LED_ON HAL_GPIO_WritePin(LED_Port,LED_Pin,GPIO_PIN_RESET)
#define LED_OFF HAL_GPIO_WritePin(LED_Port,LED_Pin,GPIO_PIN_SET)
#define LED_Toggle HAL_GPIO_TogglePin(LED_Port,LED_Pin)
#define Key_IT EXTI1_IRQn
#define Key_Port GPIOC
#define Key_Pin GPIO_PIN_1
#define Key_LED_CLK_ENABLE __HAL_RCC_GPIOC_CLK_ENABLE()
#define Key_LED_IT_ENABLE HAL_NVIC_EnableIRQ(Key_IT)
/春望的翻译
* declare */
void Key_LED_Init(void);
HAL_StatusTypeDef SysClk_Init(uint32_t m,uint32_t n,uint32_t p,uint32_t q);
int main(void){
HAL_Init();
SysClk_Init(8,336,2,7);
/* t system NVIC group */
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_1);
Key_LED_Init();
while(1);
}
韦博英语价格表
void Key_LED_Init(void){
GPIO_InitTypeDef GPIO_Init;
/* #define Key_LED_CLK_ENABLE __HAL_RCC_GPIOC_CLK_ENABLE() */
Key_LED_CLK_ENABLE;
/* #define LED_Pin GPIO_PIN_0 */
GPIO_Init.Pin = LED_Pin;
GPIO_Init.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_Init.Pull = GPIO_NOPULL;
GPIO_Init.Speed = GPIO_SPEED_LOW;
/* #define LED_Port GPIOC */
HAL_GPIO_Init(LED_Port,&GPIO_Init);
/
/ LED turn off when system ret
/* #define LED_ON HAL_GPIO_WritePin(LED_Port,LED_Pin,GPIO_PIN_RESET)      #define LED_OFF HAL_GPIO_WritePin(LED_Port,LED_Pin,GPIO_PIN_SET) */    LED_OFF;
GPIO_Init.Pin = Key_Pin;
GPIO_Init.Mode = GPIO_MODE_IT_FALLING;
GPIO_Init.Pull = GPIO_PULLUP;
GPIO_Init.Speed = GPIO_SPEED_HIGH;
HAL_GPIO_Init(Key_Port,&GPIO_Init);

本文发布于:2023-06-24 19:06:17,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/90/156319.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:中断   函数   事件   处理   抢占   程序   触发   回调
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图