历史上的今天
今天是:2024年12月11日(星期三)
2019年12月11日 | 非常完备的按键操作系统,单击、双击、N击,长按。可移植
2019-12-11 来源:elecfans
#define BaseTime 10 //时间基准10 ms ,如果设计的时基是5ms 则前面的10就用该变成5
#define number_init 0xfffffffd // 初始化相关的utime(unsigned long)变量(如果是unsigned int 就应该是0xfffd),采用这个值的好处是,即使发生时钟计数器溢出,也不影响其他的程序
typedef unsigned long utime; //这个类型是为了方便移植专门给时间相关变量使用
typedef unsigned long ulong;
typedef unsigned int uint;
typedef unsigned char uchar;
enum ButtonModel{noneClick=0,singalClick,doubleClick,repeatClick,longPress}; //doubleClick目前未定义完整动作 pressDownHold,按下保持
enum ButtonStaus{nonePress=1,pressDown,pressUp,pressDownHold}; /
struct button
{
uchar outPutEn:1; //发送数据使能
uchar lastButton:1; //按键上次变动后的状态 默认 1
uchar init_leavel:1; //设置默认按键电平
uchar longPressFlag:1; //长按释放标志 默认0,一旦开始长按则置1
uchar Gpio_level :3;
uchar applyUseOpenMaxPwm:1; //在关机状态下,若本按键按下启动了系统,则需要申请全局变量标明,禁止其他按键关闭被本按键打开的系统(自己打开自己负责关闭)
uchar ticks; //按键按下次数
enum ButtonStaus lastButtonStaus; //按键上个循环的状态
enum ButtonStaus thisButtonStaus; //按键本循环的状态
enum ButtonModel lastButtonModel; //按键上个循环所处的模式
enum ButtonModel thisButtonModel; //按键本循环应该所处的模式
uint changeModelTime; //10ms基准 //长按时间定义
uint pressLongTime; //10ms基准 //多击时间定义
utime lastPressDownMoment; //上次按键按下所处的时刻
utime thisPressDownMoment; //本次按键按下所处的时刻
uint tempTime; //缓存按键两次按下之间的时长
utime buttonConfir; //按键防抖时长
utime getTimer; //获取时钟精准时刻,用于设定按键扫描周期
utime acquisitionMoment; //获取时钟精准时刻,用于记录相同按键状态持续时长
uchar (*read_gpio)(void); //获取按键状态方法
};
/*================================
outPutEn 是为后面接收按键是单击、多击长按函数准备的参数。比如按键扫描程序10ms运行一次,输出的是单击,如果没有outPutEn这个参数,后面的接收程序会在10ms内一直都接收的是单击指令,这样就会一直执行单击需要进行的操作,本来单击一次档位变化1,结果现在档位变化了n
applyUseOpenMaxPwm 是为多按键且按键操作有优先权做准备,,有优先权的操作不会被其他按键操作打断
===============================*/
struct button button1,button2,button3;
void Scan_key(struct button *Key,utime timer ,uint enOutTime ,uint noiseProofTime)
{
enOutTime/=BaseTime;
noiseProofTime/=BaseTime;
if(number_init==Key->getTimer) //如果是第一次运行,则更新时间
{
Key->getTimer=timer;
}
else
{
if(timer-Key->getTimer>=enOutTime) //如果时间足够“定义的循环时间” ,则更新时间并允许运行
{
Key->getTimer=timer;
Key->Gpio_level=Key->read_gpio();
if(Key->Gpio_level>1);
else
{
if(Key->lastButton^Key->Gpio_level)//按键有电平变化模块处理开始----------------------------------------------------------------------------//
{
if(number_init==Key->buttonConfir)
Key->buttonConfir=timer;
if(timer-Key->buttonConfir>=noiseProofTime)//按键防抖,必须再确认状态
{
Key->lastButton=Key->Gpio_level;
Key->acquisitionMoment=number_init;
Key->buttonConfir=number_init; //二次确认标志重置
if(Key->init_leavel^Key->Gpio_level)//本次按键状态改变后与定义的电平不一致模块处理开始
{
switch(Key->lastButtonStaus)
{
case nonePress: //上个循环是定义的初始电平
case pressUp:
{
if(number_init==Key->lastPressDownMoment)//是第一次记录按键按下时刻
{
Key->thisPressDownMoment=Key->lastPressDownMoment=timer;
}
else //不第一次记录
{
Key->thisPressDownMoment=timer;
Key->tempTime+=Key->thisPressDownMoment-Key->lastPressDownMoment; //获取两次按键按下之间的时间间隔
Key->lastPressDownMoment=Key->thisPressDownMoment; //更新
}
Key->ticks++;
//不在此处增加pressLongTime判断的原因是,buftime0记录的是两次按键按下之间的时长,在两次按下之间必有弹起,一旦弹起,pressLongTime 就置零
switch(Key->ticks)
{
case 1:
{
if(Key->tempTime>=Key->changeModelTime)//ticks未初始化。
{
Key->ticks=0;
Key->tempTime=0;
}
Key->thisButtonModel=singalClick;
break;
}
case 2:
{
if(Key->tempTime Key->thisButtonModel=doubleClick; else { Key->thisButtonModel=singalClick; Key->ticks=0;
史海拾趣
|
本帖最后由 paulhyde 于 2014-9-15 09:33 编辑 总结给要参加电子设计竞赛的同学们 电子设计竞赛的近几年成为企业录用大学生的重点考察点从而带动成为大学生的热点,在参赛的同学中有很多是大二学生或者是第一次参赛的同学,或许很迷茫、不知道从 ...… 查看全部问答> |
|
对很多体育爱好者来说,奥运是一个盛大的聚会;而对组织者和当地政府而言,奥运是一次前所未有的巨大考验。在短时间内,云集众多的运动员、官员和来访者,各种突发事件和重大事件可能不期而至,对各个行业带来了巨大的压力。而医疗卫生行业作为奥运 ...… 查看全部问答> |
|
我现在拿到了一个wince 5.0的设备.上面已经有了系统, 我要是想在上面用vs2005做C#开发, 我看系统信息上说CPU是INTEL ARM920T-PX 要怎么做才能在上面开发?什么BSP.SDK..的都是什么流程? … 查看全部问答> |
|
欢 迎 大 家 加 入: 黑客开发者群:18605156,48490346,17795088,48490503 VC 群:18607590 ASP群:48490599 嵌 入 式 群:33956012加入请写名原因。 LINUX 群:18788803 经济、军事群:3685785 … 查看全部问答> |
|
CPLD中两个inout接口怎么打通,大侠们不要路过,进来说说您的方案,评优嘉奖啊 问题是这样的:一个CPLD上接了两个I2C的接口,即scl,sda和scl1,sda1,怎么将这两个I2C打通。(scl,sda是主机I2C,scl1,sda1是从机I2C) 问题相关信息搜集: I2C的scl信号是单通(input scl; output scl1),这个信号直接相连就可以, ...… 查看全部问答> |
|
嵌入式学习的点点滴滴(我的学习笔记-《鸟哥的linux私房菜》4) 好久没发帖了呢,最近几天回家了。。 在这里我想感谢soso管理员对我的支持,每次发帖她都会支持我继续写下去,谢谢 现在继续我这几天学习的总结吧。 linux一般将文件可存取访问的身份分为3个类别,分别是owner(用户),group(用户组),othe ...… 查看全部问答> |
|
启动板的打印信息显示ALSA List Device: no soundcards found.进入系统的/dev/snd目录下,只存在这timer,没有pcmC0Dx和controlC这些文件。… 查看全部问答> |




