单片机按键的定时器消抖处理
来源:互联网 发布:php抓取网页匹配url 编辑:程序博客网 时间:2024/04/29 13:40
使用定时器计时,给按键的按下、抬起的计时消抖,在大循环while里不堵塞,可以同时检测到每个按键各自的“按下”“长按”“抬起”的状态。在此基础上,按键的长按一秒、两秒三秒,按键的双击,组合键功能(例如Ctrl+C)等已经很容易实现了。
button.c和button.h直接添加到工程里,编译然后修改到对应的布尔变量。user.c是应用文件。
一、源文件button.c
按键操作。不同的编译器里布尔变量类型的几种写法:bit - bool - _Bool - unsigned char。
函数Btn_InitNull(BtnControl_pst pBtn)对按键参数初始化,设置按键初始状态为“无动作”。
函数Btn_InitPress(BtnControl_pst pBtn)对按键参数初始化,设置按键初始状态为“长按”。
函数Btn_Scan(BtnControl_pst pBtn, _Bool bPin)是在main()的大循环里检测按键状态。
#include "button.h"static _Bool Btn_Shake(BtnControl_pst pBtn, uint8_t site);/**************************************************************************Function: Btn_InitNullDescription: 初始化按键参数,状态设为:S_NULL(无动作)Input: - pBtn 按键操作结构体Return: no**************************************************************************/void Btn_InitNull(BtnControl_pst pBtn){ pBtn->status = S_NULL; pBtn->bAction = 0; pBtn->bDelay = 0;}/**************************************************************************Function: Btn_InitPressDescription: 初始化按键参数,状态设为:S_PRESS(长按)Input: - pBtn 按键操作结构体Return: no**************************************************************************/void Btn_InitPress(BtnControl_pst pBtn){ pBtn->status = S_PRESS; pBtn->bAction = 1; pBtn->bDelay = 0;}/**************************************************************************Function: Btn_ScanDescription: 获取按键状态Input: - pBtn 按键操作结构体 - bPin 按键引脚逻辑值Return: no**************************************************************************/void Btn_Scan(BtnControl_pst pBtn, _Bool bPin){ if (!bPin) { if (pBtn->bAction) // 上一状态是按下的 { pBtn->status = S_PRESS; // ===长按=== } else if (Btn_Shake(pBtn, SITE_DOWN)) // 消抖延时(记忆“按下”位置) { pBtn->bAction = 1; pBtn->status = S_DOWN; // ===按下=== } } else if (pBtn->bAction) { if (S_DOWN == pBtn->status) { pBtn->status = S_PRESS; // ===长按=== } if (Btn_Shake(pBtn, SITE_UP)) // 消抖延时(记忆“抬起”位置) { pBtn->bAction = 0; pBtn->status = S_UP; // ===抬起=== } } else { pBtn->status = S_NULL; // ===无动作=== }}/**************************************************************************Function: Btn_ShakeDescription: 使用定时器中断,做按键消抖延时Input: - pBtn 按键控制结构体 - site 按键位置Return: 执行标志**************************************************************************/static _Bool Btn_Shake(BtnControl_pst pBtn, uint8_t site){ // 开启中断延时消抖 if (!pBtn->bDelay) { pBtn->bExe = 0; pBtn->num = 0; pBtn->val = 0; pBtn->bDelay = 1; // 置位延时标志 pBtn->site = site; // 保存按键电平 } // 抖动处理 else if (pBtn->site != site) // 检测是否抖动 { pBtn->bDelay = 0; // 清零延时标志 } // 按键动作处理 else if (pBtn->bExe) { pBtn->bExe = 0; // 清零执行标志 if (++(pBtn->num) >= NUM_SHAKE) // 消抖n次 { pBtn->bDelay = 0; // 清零计时标志 return 1; // ===执行=== } } return 0; // ===不执行===}
二、头文件button.h
定义了消抖时间,按键类型。
#ifndef _BUTTON_H_#define _BUTTON_H_#include "includes.h"// 时间常数(最大为255)#define TIMER_1MS_SHAKE_BTN 1 // 1 * 5 = 5ms 实际为4 ~5ms#define TIMER_10MS_SHAKE_BTN 1 // 10 * 5 = 50ms 实际为40 ~50ms#define TIMER_10MS_SHAKE_100MS 2 // 20 * 5 = 100ms 实际为90 ~100ms#define TIMER_10MS_SHAKE_300MS 6 // 60 * 5 = 300ms 实际为290 ~300ms#define TIMER_10MS_SHAKE_500MS 10 // 100 * 5 = 500ms 实际为490 ~500ms#define TIMER_10MS_SHAKE_700MS 14 // 140 * 5 = 700ms 实际为690 ~700ms#define TIMER_10MS_SHAKE_1200MS 24 // 240 * 5 = 1200ms 实际为1190 ~1200ms#define TIMER_10MS_SHAKE_3000MS 60 // 600 * 5 = 3000ms 实际为2990 ~3000ms#define TIMER_10MS_SHAKE_5000MS 100 // 1000 * 5 = 5000ms 实际为4990 ~5000ms#define TIMER_10MS_SHAKE_12S 240 // 2400 * 5 = 12000ms 实际为11990~12000ms// 消抖次数#define NUM_SHAKE 5// 单按键状态statustypedef enum BtnStaSingle{ S_NULL, // 无动作 S_DOWN, // 按下 S_PRESS, // 长按 S_UP // 抬起} BtnStaSingle_st, *BtnStaSingle_pst;// 按键位置#define SITE_DOWN 0 // 按下#define SITE_UP 1 // 抬起// 按键控制typedef struct BtnControl{ uint8_t status:2; // 按键状态(枚举BtnStaSingle) uint8_t bAction:1; // 动作标志 uint8_t bDelay:1; // 消抖延时标志 uint8_t bExe:1; // 消抖延时执行标志 uint8_t site:1; // 按键位置 uint8_t num; // 消抖次数[0,255] uint8_t val; // 消抖延时计算值[0,255]} BtnControl_st, *BtnControl_pst;void Btn_InitNull(BtnControl_pst pBtn);void Btn_InitPress(BtnControl_pst pBtn);void Btn_Scan(BtnControl_pst pBtn, _Bool bPin);/**************************************************************************Function: Timer_BtnShakeDescription: 按键消抖计时宏函数Input: - stBtn 按键变量 - tDown 按下消抖时间 - tUp 抬起消抖时间Return: no**************************************************************************/#define Timer_BtnShake(stBtn, tDown, tUp) \{ \ if ((stBtn).bDelay) \ { \ ++(stBtn).val; \ switch ((stBtn).status) \ { \ case S_NULL: \ if ((stBtn).val >= (tDown)) \ { \ (stBtn).val = 0; \ (stBtn).bExe = 1; \ } \ break; \ case S_PRESS: \ if ((stBtn).val >= (tUp)) \ { \ (stBtn).val = 0; \ (stBtn).bExe = 1; \ } \ break; \ default: \ break; \ } \ } \}#endif /* _BUTTON_H_ */
三、应用文件user.c
1、设置单片机定时器,写中断服务函数。
2、自定义按键变量,初始化按键变量参数。
3、在中断服务里调用按键消抖计时宏函数。
4、在while里扫描按键状态,根据得到的状态值做处理。
程序里做了2、3、4步骤,第1步根据不同的单片机去写。
// 端口设置#define PIN_BUTTON RA0 // 按键volatile BtnControl_st g_stBtn;/**************************************************************************Function: mainDescription: 主函数Input: noReturn: no**************************************************************************/void main(void){ Btn_InitNull(&g_stBtn); // 按键状态初始设为“无动作” while (1) { OperateProc(); // 按键操作 }}/**************************************************************************Function: IsrDescription: 定时器中断服务 1msInput: noReturn: no**************************************************************************/void interrupt Isr(){ // ==================按键消抖延时================== Timer_BtnShake(g_stBtn, TIMER_1MS_SHAKE_BTN, TIMER_1MS_SHAKE_BTN);}/**************************************************************************Function: OperateProcDescription: 操作处理Input: noReturn: no**************************************************************************/void OperateProc(void){ Btn_Scan(&g_stBtn, PIN_BUTTON); // 按键扫描 switch (g_stBtn.status) { case S_DOWN: // ===按下=== break; case S_PRESS: // ===长按=== break; case S_UP: // ===抬起=== break; default: break; }}
阅读全文
0 0
- 单片机按键的定时器消抖处理
- 单片机的按键处理程序
- 51单片机:利用定时器中断写一个简易加法计算器,按键消抖算法很好。
- 单片机---多功能按键处理
- 单片机按键消抖程序
- 51单片机按键消抖
- 8.6 单片机按键消抖
- 单片机通过软件实现按键消抖
- (驱动)(中断)(定时器)中断结合定时器完成按键消抖的驱动程序
- Linux按键驱动程序、定时器消抖
- 嵌入式S3C2440按键消抖--定时器操作
- 按键消抖(定时器中断)
- 基于proteus的51单片机仿真实例五十二、按键的判断与消抖实例
- 单片机按键去抖原理
- 单片机按键去抖原理
- 单片机按键去抖原理
- 51单片机的定时器/计数器
- 单片机 定时器计数器的相关
- ASP.NET – Web 页面
- Android 删除多个activity的类,进入多个activity
- ZZULIOJ【1088】手机短号【输入输出格式】
- php 支付宝App支付服务端操作
- C++预科——C语言指针回顾(一)理解指针和指针指向的内容
- 单片机按键的定时器消抖处理
- 浏览器异常捕获(适用场景:解决报错后,程序无法执行的问题)
- Tomcat配置
- 笔记
- C# 给某个方法设定执行超时时间
- HDU
- localStorage的使用总结
- Android thinker
- codeforces 835 a Key races