特别声明并致敬:本文思想及代码来自-->[点击网址跳转] https://www.cnblogs.com/yangfengwu/p/11669354.html
实现的功能(按键的状态)
1. 检测到按键按下
2. 检测到按键按下一定时间
3. 检测到按键松开(按下后的松开)
4. 检测到按键松开一定时间
注意:示例代码中,
1. 检测按下,检测按下一定时间,不能同时使用;
2. 检测松开,检测松开一定时间,不能同时使用;
用到的资源
1. 引脚的输入
2. 1ms定时器
3. 主循环扫描处理
4. 全局变量
单个按键处理的思路
1. 主程序中不断扫描按键引脚的状态,根据引脚状态判断按键按下或松开的状态,执行不同的代码;
2. 在1ms定时器中,对不同状态下,自增消抖变量,自增松开或按下的时间;
3. 在主程序扫描函数中,处理不同状态的跳转。
建立全局变量:int KeySmartConfig[7]={0};
KeySmartConfig[0] | KeySmartConfig[1] | KeySmartConfig[2] | KeySmartConfig[3] | KeySmartConfig[4] | KeySmartConfig[5] | KeySmartConfig[6] |
消抖变量 | 按下标记 | 松开标记 | 按下标记拷贝 | 松开变价拷贝 | 按下时间(ms) | 松开时间(ms) |
1.扫描按键按下, 判断按下标记未置位,表明是刚按下,消抖自增; 超时后,清空消抖变量,置位按下标记,复位松开标记; 2.扫描按键松开,消抖自增; 超时后,清空消抖变量, 判断依然松开,置位松开标记,复位按下标记 |
1.消抖后,判断按键按下,置位; 2.消抖后,判断按键松开,复位 表示按键已按下(与松开互斥) |
1.消抖后,判断按键松开,置位; 2.消抖后,判断按键按下,复位 表示按键已松开(与按下互斥) |
1. 随着按下标记的状态而改变 2. 主程序中, 判断置位时,检测按下时间超时, 则状态为按下一定时间 |
1. 随着松开标记的状态而改变 2. 主程序中, 判断置位时,检测按下时间超时, 则状态为松开一定时间 |
在1ms定时器中 按下标记若置位,自增; 按下标记若复位,清零 |
在1ms定时器中 松开标记若置位,自增; 松开标记若复位,清零 |
具体代码:
smart_key.h
#ifndef __SMART_KEY_H_ #define __SMART_KEY_H_ #ifndef __KEY_C_ #define __KEY_C_ extern #else #define __KEY_C_ #endif #include "key.h" #define KeySmartConfigDown 0 /* 按下电平 0-低电平表示按下, 1-高电平表示松开 */ #define SmartConfigKeyPinIn GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2) //PE2 /* 检测的按键引脚 */ __KEY_C_ int KeySmartConfig[7]; //消抖变量||按下标记||松开标记||按下标记考别||按下时间(ms)||松开时间(ms) void SmartConfigKey(void); #endif
smart_key.c
#include "smart_key.h" int KeySmartConfig[7]={0}; //消抖变量||按下标记||松开标记||按下标记拷贝||松开标记拷贝||按下时间(ms)||松开时间(ms) //按键处理 void SmartConfigKey(void) { if(SmartConfigKeyPinIn == KeySmartConfigDown) //扫描到按键按下 { if(KeySmartConfig[1] == 0) //判断按下标记为0,表示上次扫描未按下 { KeySmartConfig[0] ++; //自增消抖变量 if(KeySmartConfig[0] >= 500) //消抖完成,判断按键按下 { KeySmartConfig[0] = 0; //清空消抖变量 KeySmartConfig[2] = 0; //清空松开标记 KeySmartConfig[1] = 1; //置位按下标记 KeySmartConfig[3] = 1; //拷贝按下标记 KeySmartConfig[4] = 0; //拷贝松开标记 } } }else //扫描到按键松开 { KeySmartConfig[0]++; //自增消抖变量 if(KeySmartConfig[0] > 2000) //判断松开 { KeySmartConfig[0] = 0; //清空消抖变量 if(KeySmartConfig[1] == 1) //消抖完成,判断按下后松开 { KeySmartConfig[2] = 1; //置位松开标记 KeySmartConfig[1] = 0; //清空按下标记 KeySmartConfig[3] = 0; //拷贝按下标记 KeySmartConfig[4] = 1; //拷贝松开标记 } } } }
1ms定时器中断
timer.c
//定时器3中断服务函数 void TIM3_IRQHandler(void) { if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断 { if(KeySmartConfig[1]) { KeySmartConfig[5]++; }else { KeySmartConfig[5] = 0; } if(KeySmartConfig[2]) { KeySmartConfig[6]++; }else { KeySmartConfig[6] = 0; } } TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除中断标志位 }
主程序使用
while(1) { SmartConfigKey(); //扫描按键 //例1: 检测到按键按下,执行某端代码 // if(KeySmartConfig[3] == 1) //判断按键按下:"拷贝的按下按键标记"置位 // { // KeySmartConfig[3] = 0; //清空后,只有按键松开再按下的时候才会进入 // // //执行的代码 // u3_printf(" 按键按下 "); // } //例2:检测到按键按下,然后根据按下时间执行某段代码 if(KeySmartConfig[3] == 1) { if(KeySmartConfig[5] >= 3000) //按下时间大于3s { KeySmartConfig[3] = 0; //清空后,只有按键松开再按下的时候才会进入 //执行的代码 u3_printf(" 按键按下持续时间大于3s "); } } // //例3:检测到按键松开执行某段代码 // if(KeySmartConfig[4] == 1) // { // KeySmartConfig[4] = 0; //清空后,只有按键按下再松开的时候才会进入 // // //执行的代码 // u3_printf(" 按键按下后松开 "); // // } //例4:检测到按键松开,然后根据松开时间执行某段代码 if(KeySmartConfig[4] == 1) { if(KeySmartConfig[6] >= 3000) //松开时间大于3s { KeySmartConfig[4] = 0; //清空后,只有按键按下再松开的时候才会进入 //执行的代码 u3_printf(" 按键松开时间大于3s "); } } } }