HAL库GPIO中断
一、NVIC寄存器
typedef struct
{
__IOM uint32_t ISER[8U]; /*中断使能寄存器*/
uint32_t RESERVED0[24U];
__IOM uint32_t ICER[8U]; /*中断清除使能寄存器*/
uint32_t RSERVED1[24U];
__IOM uint32_t ISPR[8U]; /*中断使能挂起寄存器*/
uint32_t RESERVED2[24U];
__IOM uint32_t ICPR[8U]; /*中断解挂寄存器*/
uint32_t RESERVED3[24U];
__IOM uint32_t IABR[8U]; /*中断有效位寄存器*/
uint32_t RESERVED4[56U];
__IOM uint8_t IP[240U]; /*中断优先级寄存器*/
uint32_t RESERVED5[644U];
__OM uint32_t STIR; /*软件触发中断寄存器*/
} NVIC_Type;
二、NVIC相关函数
1.HAL_NVIC_SetPriorityGrouping设置中断优先级分组函数
/*形参:PriorityGroup中断优先级分组号:可选NVIC_PRIORITYGROUP_0到NVIC_PRIORITYGROUP_4*/
void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
{
/* Check the parameters */
assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
/* Set the PRIGROUP[10:8] bits according to the PriorityGroup parameter value */
NVIC_SetPriorityGrouping(PriorityGroup);
}
2.HAL_NVIC_SetPriority设置中断优先级函数
用于设置中断的抢占优先级和响应优先级
/*形参1是中断号(stm32f103xe.h里面有),形参2是抢占优先级0-15,响应优先级是0-15*/
void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)
{
uint32_t prioritygroup = 0x00U;
/* Check the parameters */
assert_param(IS_NVIC_SUB_PRIORITY(SubPriority));
assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority));
prioritygroup = NVIC_GetPriorityGrouping();
NVIC_SetPriority(IRQn, NVIC_EncodePriority(prioritygroup, PreemptPriority, SubPriority));
3.HAL_NVIC_EnableIRQ中断使能函数
void HAL_NVIC_EnableIRQ(IRQn_Type IRQn)
{
/* Check the parameters */
assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
/* Enable interrupt */
NVIC_EnableIRQ(IRQn);
}
4.HAL_NVIC_DisableIRQ中断除能函数
void HAL_NVIC_DisableIRQ(IRQn_Type IRQn)
{
/* Check the parameters */
assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
/* Disable interrupt */
NVIC_DisableIRQ(IRQn);
}
5.HAL_NVIC_SystemReset系统复位函数
用于软件复位系统
void HAL_NVIC_SystemReset(void)
{
/* System Reset */
NVIC_SystemReset();
}
三、EXTI的HAL库驱动
外部中断配置步骤
(1)使能对应GPIO口时钟
(2)设置GPIO口工作模式,触发条件,开启AFIO时钟,设置IO口与中断线的映射关系
全部封装在HAL_GPIO_Init函数中
(3)配置中断优先级(NVIC),并使能中断
(4)编写中断服务函数
没开启一个中断,就必需编写对应的中断服务函数,否则会死机。中断服务函数接口已经在stm32f103xe.h中做好了,STM32F1的IO口外部中断函数只有7个
void EXIT0_IRQHandler();
void EXIT1_IRQHandler();
void EXIT2_IRQHandler();
void EXIT3_IRQHandler();
void EXIT4_IRQHandler();
void EXIT9_5_IRQHandler();
void EXIT15_10_IRQHandler();
0-4每个中断对应一个中断函数,中断线5-9共用中断函数EXIT9_5_IRQHandler(),中断线10-15共用EXIT15_10_IRQHandler()。一般情况下,我们可以把中断控制逻辑直接编写在中断服务函数中,但是HAL库把中断处理过程进行了简单封装。
(5)编写中断处理回调函数HAL_GPIO_EXTI_Callback
HAL库为了用户使用方便,提供了一个中断通用入口函数HAL_GPIO_EXTI_IRQHandler,在函数内部直接调用回调函数HAL_GPIO_EXTI_Callback
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
/* EXTI line interrupt detected */
if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != 0x00u)
{
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
HAL_GPIO_EXTI_Callback(GPIO_Pin);
}
}
通过入口参数GPIO_Pin判断来自哪个IO口,然后清除相应的中断标志位,最后调用HAL_GPIO_EXTI_Callback来实现逻辑。
举个例子
#include "./BSP/EXTI/exti.h"
#include "./BSP/LED/led.h"
#include "./BSP/KEY/key.h"
#include "./SYSTEM/delay/delay.h"
void EXTI3_IRQHandler(void)
{
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_3); /* 调用中断处理公用函数 清除KEY0所在中断线 的中断标志位 */
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_3); /* HAL库默认先清中断再处理回调,退出时再清一次中断,避免按键抖动误触发 */
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
delay_ms(20);//消抖
if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_3)==0)
{
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);
}
}
void extix_init(void)
{
GPIO_InitTypeDef gpio_init_struct;
__HAL_RCC_GPIOE_CLK_ENABLE(); /* IO口PE时钟使能 */
gpio_init_struct.Pin=GPIO_PIN_3;
gpio_init_struct.Mode=GPIO_MODE_IT_FALLING; /*下降沿触发中断*/
gpio_init_struct.Pull=GPIO_PULLUP; /*上拉电阻*/
//gpio_init_struct.Speed=GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOE, &gpio_init_struct); /*初始化引脚*/
HAL_NVIC_SetPriority(EXTI3_IRQn, 0, 2);
HAL_NVIC_EnableIRQ(EXTI3_IRQn);
}
int main(void)
{
HAL_Init();/*初始化HAL库*/
sys_stm32_clock_init(RCC_PLL_MUL9);/*设置时钟,72Mhz*/
delay_init(72);
led_init();
//key_init();
extix_init();
while (1)
{
delay_ms(1000);
}
}
1107

被折叠的 条评论
为什么被折叠?



