OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 8547|回复: 5

分享一个按键函数-----欢迎拍砖

[复制链接]

10

主题

271

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1236
金钱
1236
注册时间
2015-5-14
在线时间
352 小时
发表于 2015-10-27 18:39:28 | 显示全部楼层 |阅读模式
一个按键,分为长按和短按的中间层。

#ifndef __KEY_H__
#define __KEY_H__



#include "../heard/include.h"


struct key_struct
{
_UBYTE IO_ValueReadLase;
_UBYTE IO_ValueReadNow;
_UBYTE IO_ValueCnt;


_UBYTE IO_ValueNow;
_UBYTE IO_ValueLast;
_UBYTE IO_Value;

_UBYTE IO_ValueActionLast;
_UBYTE IO_ValueActionNow;
};







/***************************按键驱动相关********************************/
#define KEY_COLUMN2_Direction TRISCbits.TRISC1
#define KEY_COLUMN2 PORTCbits.RC1

#define KEY_ROW2_Direction TRISBbits.TRISB0
#define KEY_ROW2 PORTBbits.RB0

#define KEY_IO_Init() do{ \
KEY_COLUMN2_Direction=OUTPUT_PIN; \
KEY_COLUMN2=0; \
TRISBbits.TRISB0=INPUT_PIN; \
}while(0)

#define KEY_IO_Value() (KEY_ROW2) //返回按键IO口值



/***************************配置相关***********************************/
#define KEY_READ_TIMERS 10 //消抖次数


#define KET_LongTimers 200 //长按时间=N*心跳时间


#define KEY_NormalValue 0x01 //按键常态值


/***************************相关函数************************************/
void KEY_Init(void); //初始化函数


void KEY_ReadValue(void); //放到心跳定时器中


//按键状态
#define KEY_InvalidState 0
#define KEY_ShortState 1
#define KEY_LongState 2

_UBYTE KEY_ReturnState(void); //用户调用,返回按键状态

//清除按键状态,当用户调用KEY_ReturnState(),
//执行完相应动作后,需要调用此函数清除按键状态,
//否则,如果硬件驱动按键状态没有改变,则会重复执行。
void KEY_ClearFlag(void);

















#endif


#include "../heard/key.h"


static struct key_struct key_value;

static _UWORD KET_LongTimersCnt;


void KEY_Init(void)
{
KEY_IO_Init();

KET_LongTimersCnt=0;

key_value.IO_ValueReadLase =KEY_NormalValue;
key_value.IO_ValueReadNow =KEY_NormalValue;
key_value.IO_ValueCnt =0;
key_value.IO_ValueNow =KEY_NormalValue;
key_value.IO_ValueLast =KEY_NormalValue;
key_value.IO_Value =KEY_InvalidState;
key_value.IO_ValueActionLast=KEY_InvalidState;
key_value.IO_ValueActionNow =KEY_InvalidState;
}


void KEY_ReadValue(void)
{
key_value.IO_ValueReadNow=KEY_IO_Value();

if(key_value.IO_ValueReadNow != key_value.IO_ValueReadLase)
{
key_value.IO_ValueReadLase=key_value.IO_ValueReadNow;
key_value.IO_ValueCnt=0;
return;
}
key_value.IO_ValueCnt++;

if(key_value.IO_ValueCnt>=KEY_READ_TIMERS)
{
key_value.IO_ValueCnt=0;
key_value.IO_ValueNow=key_value.IO_ValueReadNow;
}

if(key_value.IO_ValueNow != KEY_NormalValue)
{
if(KET_LongTimersCnt<KET_LongTimers) KET_LongTimersCnt++;
}
else
{
KET_LongTimersCnt=0;
}

if(KET_LongTimersCnt>=KET_LongTimers)
{
key_value.IO_Value=KEY_LongState;

if(key_value.IO_Value != key_value.IO_ValueActionLast)//防止按键一直按着,重复判定按键状态
{
key_value.IO_ValueActionLast=key_value.IO_Value;
key_value.IO_ValueActionNow=key_value.IO_Value;
}
}
else
{
if((key_value.IO_ValueLast!=KEY_NormalValue) && (key_value.IO_ValueNow==KEY_NormalValue))
{
if(key_value.IO_Value!=KEY_LongState)//防止按键松开,误认为短按
{
key_value.IO_Value=KEY_ShortState;

if(key_value.IO_Value != key_value.IO_ValueActionLast)//防止按键一直按着,重复判定按键状态
{
key_value.IO_ValueActionLast=key_value.IO_Value;
key_value.IO_ValueActionNow=key_value.IO_Value;
}
}
}
else
{
if((key_value.IO_ValueLast==KEY_NormalValue) && (key_value.IO_ValueNow==KEY_NormalValue))
{
key_value.IO_Value=KEY_InvalidState;
if(key_value.IO_Value != key_value.IO_ValueActionLast)//防止按键一直按着,重复判定按键状态
{
key_value.IO_ValueActionLast=key_value.IO_Value;

if(!key_value.IO_ValueActionNow)//防止按键函数来不及动作,状态被清除
key_value.IO_ValueActionNow=key_value.IO_Value;
}
}
}
}


key_value.IO_ValueLast = key_value.IO_ValueNow;
}

_UBYTE KEY_ReturnState(void)
{
return key_value.IO_ValueActionNow;
}

void KEY_ClearFlag(void)
{
key_value.IO_ValueActionNow = KEY_InvalidState;
}







30年众生牛马,60年诸佛龙象!
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

10

主题

271

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1236
金钱
1236
注册时间
2015-5-14
在线时间
352 小时
 楼主| 发表于 2015-10-27 18:40:40 | 显示全部楼层
希望大家多多交流,共同进步!
30年众生牛马,60年诸佛龙象!
回复 支持 反对

使用道具 举报

120

主题

7877

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12010
金钱
12010
注册时间
2013-9-10
在线时间
427 小时
发表于 2015-10-27 21:09:35 | 显示全部楼层
谢谢分享!!!!!
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

9

主题

538

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3371
金钱
3371
注册时间
2015-1-7
在线时间
794 小时
发表于 2015-10-28 09:57:58 | 显示全部楼层
感谢分享~楼主分享的都很实用。
之前也写过一个按键的状态机,返回按下事件,松开事件,长按事件,短按事件等,可以配置按键个数,每个按键的防抖时间,长短按识别时间,电平定义,IO的操作留了操作函数接口。是公司的项目代码不便分享,我回头重写一个和大家一起讨论啊
机器生汇编,汇编生B,B生C,C生万物.... 经过长期对C语言的研究,目前只有两个方面不懂:这也不懂,那也不懂
https://github.com/ianhom
回复 支持 反对

使用道具 举报

10

主题

271

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1236
金钱
1236
注册时间
2015-5-14
在线时间
352 小时
 楼主| 发表于 2015-10-28 10:40:23 | 显示全部楼层
回复【4楼】ianhom:
---------------------------------
好的,等发上来,通知我,一起讨论下。我发的程序,都是把驱动层函数接口留出来,不直接在中间层调用,一般都定义成宏函数,然后给应用层提供接口函数,屏蔽掉内部实现。
30年众生牛马,60年诸佛龙象!
回复 支持 反对

使用道具 举报

22

主题

117

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
798
金钱
798
注册时间
2015-10-24
在线时间
160 小时
发表于 2016-6-7 17:02:35 | 显示全部楼层
谢谢分享。。。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 11:45

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表