前言
前一篇按键模块的文章我们封装了按键的功能函数等,现在为什么又需要改进呢?因为在前面我们使用的是延时函数进行的消抖,延时函数在项目开发中最好就是少使用。延时函数的大量使用会造成系统的卡顿,所以这里我们使用外部中断改进按键的代码。
外部中断的介绍:外部中断
按键模块化:按键模块化
下面我们直接上代码,原理部分请大家看之前的文章。
一、代码部分
driver_key.h
#ifndef __DRIVER_KEY_H #define __DRIVER_KEY_H #include "main.h" #define Key1_Pin GPIO_PIN_4 #define Key1_GPIO_Port GPIOE #define Key2_Pin GPIO_PIN_3 #define Key2_GPIO_Port GPIOE #define KEY1_GPIO_CLK_EN() __HAL_RCC_GPIOE_CLK_ENABLE() #define KEY2_GPIO_CLK_EN() __HAL_RCC_GPIOE_CLK_ENABLE() #define Key1() HAL_GPIO_ReadPin(Key1_GPIO_Port, Key1_Pin) #define Key2() HAL_GPIO_ReadPin(Key2_GPIO_Port, Key2_Pin) uint8_t Getkey1val(void); uint8_t Getkey2val(void); void key_init(void); #endif
driver_key.c
这里我们把按键设置为了外部中断,而且是双边沿触发,当按键按下或者松开时都会触发外部中断,在外部中断中我们进行按键值的读取,并编写一个函数返回按键值,供应用程序调用。
#include "driver_key.h" uint8_t key1_val = 0; uint8_t key2_val = 0; void key_init(void) { // 定义GPIO的结构体变量 GPIO_InitTypeDef GPIO_InitStruct = {0}; // 使能按键的GPIO对应的时钟 KEY1_GPIO_CLK_EN(); KEY2_GPIO_CLK_EN(); GPIO_InitStruct.Pin = Key1_Pin; GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; // 设置为双边沿触发外部中断 GPIO_InitStruct.Pull = GPIO_PULLUP; // 默认上拉 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; // 引脚反转速度设置为快 // 初始化引脚配置 HAL_GPIO_Init(Key1_GPIO_Port, &GPIO_InitStruct); GPIO_InitStruct.Pin = Key2_Pin; GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; // 设置为双边沿触发外部中断 GPIO_InitStruct.Pull = GPIO_PULLUP; // 默认上拉 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; // 引脚反转速度设置为快 // 初始化引脚配置 HAL_GPIO_Init(Key2_GPIO_Port, &GPIO_InitStruct); HAL_NVIC_SetPriority(EXTI3_IRQn, 0, 0);// 设置外部中断优先级 HAL_NVIC_EnableIRQ(EXTI3_IRQn);// 使能外部中断 HAL_NVIC_SetPriority(EXTI4_IRQn, 0, 0);// 设置外部中断优先级 HAL_NVIC_EnableIRQ(EXTI4_IRQn);// 使能外部中断 } //外部中断3中断处理函数 void EXTI3_IRQHandler(void) { HAL_GPIO_EXTI_IRQHandler(Key2_Pin); } //外部中断4中断处理函数 void EXTI4_IRQHandler(void) { HAL_GPIO_EXTI_IRQHandler(Key1_Pin); } //外部中断回调函数 void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if(GPIO_Pin == Key1_Pin) { key1_val = Key1(); } else if(GPIO_Pin == Key2_Pin) { key2_val = Key2(); } } //返回key1按键值 uint8_t Getkey1val(void) { return key1_val; } //返回key2按键值 uint8_t Getkey2val(void) { return key2_val; }
maic.c
if(Getkey1val() == 0) { LED0(ON); } else if(Getkey1val() == 1) { LED0(OFF); }
总结
使用外部可以减少延时函数的使用,而且还能使得按键更加灵敏。