#include "key.h"
#define U1 P17
#define D1 P54
#define U2 P55
#define D2 P32
#define LONG_TIME 50 //长按时间50,时间乘以定时器时间
#define CLICK_TIME 10 //单击时间
#define POP_UP_TIME 50 //按键弹起时间
#define FILTEER_TIME 5 //滤波时间
#define LONG_PRESS 3 //长按
#define DBLCLICK 2 //双击
#define CLICK 1 //单击
static uchar Key_Num[KEY_QUANTITY] = {0}; //存放按键io的值
static uint KeyDown[KEY_QUANTITY] = {0}; //按键按下计数
static uchar KeyRelease[KEY_QUANTITY] = {0}; //按键释放计数
static uchar Key_Flag[KEY_QUANTITY] = {0}; //按键是否按下过计数
//uchar Key_Value[KEY_QUANTITY] = {0}; //存放按键键值,不记录按下时间用节省内存
uint Key_Value[KEY_QUANTITY] = {0}; //存放按键键值,记录按键按下时间用,
static void key() //获取io的值
{
int i = 0;
Key_Num[i++] = U1;
Key_Num[i++] = D1;
Key_Num[i++] = U2;
Key_Num[i++] = D2;
}
/*
按键键值:1:单击
2:双击
3:长按
键值单击和双击需要手动清零,长按松开自动置零
返回值:指向按键键值的指针,记录按下时间时由于是int数组,使用时需要强转一下uint *key=(uint*)Key_Read()
*/
uchar *Key_Read(void)
{
int i = 0;
key(); //获取io的值
for (i = 0; i < KEY_QUANTITY; i++)
{
if (Key_Num[i] == 0)
{
KeyDown[i]++; //按下计数自加
if (KeyRelease[i] == 0)
KeyRelease[i] = 1; //没有被按下过设置为1
if (KeyDown[i] > LONG_TIME)
/*按下时间超过LONG_TIME认为是长按,定时器时间,不会记录按下时间*/
//Key_Value[i] = LONG_PRESS;
/*记录长按时间,Key_Value*定时器时间=按下时间,最大值65535,溢出最小值3,没溢出最小值LONG_TIME*/
Key_Value[i] = KeyDown[i]>LONG_PRESS?KeyDown[i]:LONG_PRESS;
else if (KeyDown[i] > CLICK_TIME && KeyRelease[i] > CLICK_TIME)
Key_Flag[i] = 1; //按下计数超过设定,同时松开时间也超过设定认为是双击
}
else if (KeyRelease[i]) //松开时间计数
{
if (Key_Value[i] >= 3 || KeyDown[i] < FILTEER_TIME)
{ //长按松开或按下时间太短清零计数
KeyRelease[i] = 0; //??????????
KeyDown[i] = 0;
Key_Value[i] = 0;
continue; //退出不执行下面的if
}
if (KeyRelease[i]++ > POP_UP_TIME) //按键松开时间计数超过设定值
{
KeyRelease[i] = 0; //??????????
KeyDown[i] = 0;
if (Key_Flag[i]) //按键被按下过2次
{
Key_Value[i] = DBLCLICK; //设定为双击
Key_Flag[i] = 0;
}
else
Key_Value[i] = CLICK; //否则单击
}
}
}
return Key_Value;
}
STC8单片机的按键单击、双击、长按的代码实现
需积分: 0 174 浏览量
更新于2022-06-24
11
收藏 81KB ZIP 举报
在STC8单片机编程中,实现按键的单击、双击和长按功能是一项基本但至关重要的任务。这通常涉及到硬件接口设计、中断处理和时间管理等多个方面。下面我们将详细探讨这些知识点。
我们需要了解STC8单片机。STC8系列是宏晶科技(STC)推出的一系列低功耗、高性能的8位单片机,广泛应用于各种嵌入式系统。它们拥有丰富的I/O端口,支持在线编程和调试,适合初学者和专业开发者使用。
1. **硬件接口设计**:
按键通常连接到单片机的输入引脚,通过上拉或下拉电阻来检测按键状态。当按下按键时,输入引脚的电平会发生变化,这个变化可以被单片机读取。例如,使用上拉电阻时,未按下按键时引脚为高电平,按下时变为低电平。
2. **中断处理**:
为了实时响应按键操作,我们可以设置中断服务程序。当按键状态改变时,触发中断,然后在中断服务程序中处理按键事件。STC8单片机支持多种中断源,包括外部中断,我们可以通过配置中断控制器来选择合适的中断模式。
3. **代码实现**:
在C语言中,我们需要定义一个结构体或类来存储按键的状态信息,如当前状态、上一次状态、按键按下时间等。接下来,编写一个定时器中断服务程序,定期检查按键状态。这里有两个关键点:滤波和去抖动。滤波是为了消除因机械抖动导致的误触发;去抖动则是为了避免因为按键物理弹跳而产生的多次中断。
4. **单击、双击和长按识别**:
- **单击**:在一段时间内(比如50ms),检测到按键由低到高或由高到低的转换,就可以认为是一次单击。
- **双击**:在更短的时间间隔(如300ms)内,连续两次单击被视为双击。这需要在单击检测的基础上添加计数和时间间隔判断。
- **长按**:如果按键保持低电平或高电平超过一定时间(如1秒),则视为长按。可以设定一个计时器,当按键状态持续一段时间后启动另一个事件。
5. **移植性**:
描述中提到的“也可以简单地移植到其他平台”,意味着这段代码可能采用了通用的设计模式和API,使得它可以在不同的单片机或嵌入式系统中复用。关键在于抽象出与具体硬件无关的部分,如中断处理和时间管理,这样就能轻松地将代码移植到支持类似功能的其他微控制器。
6. **项目文件分析**:
压缩包中的文件可能是工程文件和源代码文件。例如,`KEY.uvgui.Administrator`可能是用户界面相关的配置文件,`KEY.uvopt`可能是编译选项,`KEY.uvproj`是Keil μVision项目文件,`Objects`包含了编译生成的目标文件,`.vscode`可能包含VSCode的配置信息,`Listings`存储了源码的列表文件,而`HAREWARE`可能包含了与硬件接口相关的头文件或配置。
实现STC8单片机的按键单击、双击和长按功能涉及硬件接口设计、中断服务程序、时间管理和代码的可移植性。通过理解这些知识点,我们可以有效地处理按键输入,并将其应用到各种嵌入式系统中。
qq_43446733
- 粉丝: 9
- 资源: 3
最新资源
- RC振荡电路——文氏桥振荡电路(OP07仿真)_文氏桥振荡器-CSDN博客.mhtml
- vs2022安装包,推荐安装社区版
- 固件开发项目实例1000例实例(26)--智能家居安全系统的固件设计.docx
- 固件开发项目实例1000例实例(24)--智能健康手环的固件设计.docx
- 基于Simulink的小波变换滤波器.docx
- 吉林大学2024就业质量年度报告
- 常用工具:谷歌浏览器安装包
- FPC0.5立贴, footprint expert封装
- DigiShow 教程5 艺术灯光应用
- DigiShow 教程6 数码音乐应用
- pikachu-master.zip
- DigiShow 教程7 互动装置应用
- DigiShow 教程8 表达式和脚本
- Word自动填表组件-发票打印,报名表自动生成
- FPC0.5l立贴, footprint expert封装
- 复旦大学计算机网络课后习题及答案.zip