如图可知,配置流程分成以下一个部分
①使能GPIO时钟 __HAL_RCC_GPIOA_CLK_ENABLE();// 打开时钟
②初始化利用 HAL_GPIO_Init 一步到位,可以初始化外设GPIO的一切 4个参数 (引脚 Pull 这里选择的模式 是从下面这几个里面选 速度)
③在main()函数的HAL_Init() 中 选择HAL_NVINVICC_SetPriorityGrouping即设置NVIC优先级分组加下表
一般选择用2:2
⑤在初始化函数中设置优先级和使能中断
优先级:void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority) 参数1是STM32 的特殊中断数字见图 参数2是抢占优先级的等级 参数3是 响应优先级的等级 注等级越低越优先
选择特殊中断数字根据引脚选定 例如PA0 则选择EXTI0_IRQn PB4则选择EXTI4_IRQn 这个选择也影响了后面的选择
使能:void HAL_NVIC_EnableIRQ(IRQn_Type IRQn) 参数为特殊中断数字
⑥编写 中断服务函数void EXTI0_IRQHandler(void) ,专门用于处理 EXTI0(外部中断 0) 触发的中断事件。
在内部包含公共中段服务函数 void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
⑦在HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);函数中有自定义的void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)函数 需要编写想要的中断效果
以下是中断exti.c文件代码
cs
#include "exti.h"
#include "sys.h"
#include "delay.h"
#include "led.h"
GPIO_InitTypeDef exti_initstruct;
void exti_init(void)
{
//打开时钟
__HAL_RCC_GPIOA_CLK_ENABLE(); //注意看硬件原理图中key的引脚在哪一个组
//调用GPIO初始化函数
exti_initstruct.Pin = GPIO_PIN_0;
exti_initstruct.Pull = GPIO_PULLUP;
exti_initstruct.Mode =GPIO_MODE_IT_FALLING;
exti_initstruct.Speed =GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA,&exti_initstruct);
HAL_NVIC_SetPriority(EXTI0_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(EXTI0_IRQn);
}
void EXTI0_IRQHandler(void)
{
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
delay_ms(20); //消抖
if(GPIO_Pin == GPIO_PIN_0) //判断是不是在引脚0的位置
{
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==GPIO_PIN_RESET) //如果在引脚0的位置则判断该处的引脚是否是低电平
led1_toggle(); //若低电平则翻转
}
}
以下是主函数 main()的代码
cs
#include "sys.h"
#include "delay.h"
#include "led.h"
#include "exti.h"
int main(void)
{
HAL_Init(); /* 初始化HAL库 */
stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
led_init();
exti_init();
while(1)
{
led2_toggle();
delay_ms(500);
}
}
注意主函数 只需要调用exti_init()就可以了因为其他函数都连带在里面