三星t705c后面2个按键zhaot

三行按键扫描简单消抖程序
(amoBBS 阿莫电子论坛) -
三行按键扫描简单消抖程序
本帖最后由 rain73 于
01:13 编辑
看了“新型的按键扫描程序”:
/forum.php?mod=viewthread&tid=4308630
用异或判断跳变的方法很好,可惜帖子中按键消抖的方法是个摆设,没有意义。自己改进了一下,发出来给大家讨论下看正确与否。
void KeyRead() {
& & static u8 tmp, ii=0;
& & if (ii==0) {
& && &ii = 1;
& && &tmp = P1 ^ 0xFF;
& & } else {
& && &ii = 0;
& && &Curr = P1 ^ 0xFF;
& && &if (Curr != tmp)
& & TrgDown = Curr & (Curr ^ Prev);& && &//Down跳变
& & TrgUp& &= Prev & (Curr ^ Prev);& && &//Up跳变
& & Prev = C& && && && && && && && & //前次值
只需改进一下KeyRead()函数即可,其它不变。消抖的原理是把原来KeyRead()执行一次就输出结果,变为执行两次才输出结果。
第一次执行把键盘口扫描值放tmp暂存,第二次判断是否与第一次的值相等,相等则输出结果,不等则退出重复上述过程。
虽然仅是二次扫描,但总算不是原贴中的假把式。类似的,可以如法炮制多次扫描,但会变得复杂失去本程序简洁的意义,不
如直接上状态机键盘算法。
上述是基于51的程序,把原来的变量命名改了一下,使之更容易理解。
Curr& &键口当前值
Prev& &键口上次值
TrgDown压键跳变
TrgUp& & 抬键跳变
顺便把我的实验执行函数也贴出来吧:
void KeyProc() {
& & //短按单次执行
& & if (KEY1 & TrgDown) {
& && &LED1 = 0;
& & } else {
& && &LED1 = 1;
& & //长按多次执行
& & if (KEY1 & Prev) {& && &//KEY1键按下
& && &if (i++ &= 100) {
& && && && &i = 90;& && && &//重复执行周期(100-90)*T (T为键盘扫描周期,例如10ms)
& && && && &LED2 = 0;
& && &} else {
& && && && &LED2 = 1;
& & } else {& && && && && & //KEY1键松开(重新初始化参数)
& && &i = 0;& && && && &//长按时间(100-0)*T
& && &LED2 = 1;
鉴于有人看不懂,把主程序也放上来吧:
#define KEY1 0x40
sbit LED1 = P3^2;
sbit LED2 = P3^3;
u8 TrgDown, TrgUp;& && &//跳变值
u8 P& && && && && & //前次值
/* 主函数 */
void main() {
& & while (1) {
& && &KeyRead();
& && &KeyProc();
& && &Delay_10& &//模拟中断扫描,10ms扫描一次,实际使用把KeyRead()放入中断处理中。
为了测试消抖的效果,用串口观察函数的执行,在KeyRead()中:
if (Curr != tmp)
if (Curr != tmp) {
& & printf(&抖动\n&);
终端截图:
可以发现,几乎每次的压键和抬键的过程中,都可以捕捉到“抖动”,这里的“抖动”,并非完全是抖动,
如果第一次采样时刚好是按下前,第二次采样是按下后,二次的值不一样,也是当消抖处理,下二次采样
才有效,这样处理按键更加牢靠。同理,抬键时也是同样的过程。除了这两种情况,其它就是真实的按键
抖动被捕捉到了。
收藏,试验下
我完全看不出来KeyRead()是如何执行两次才输出结果???
原本高大上的东西被你搞得如此不堪。
if(READ_KEY)& & & & key_tmp = 1;
if(key_tmp & (key_tmp ^ key_cnt)
& & & & key_time = 0;
key_cnt = key_
if(key_time & 5)& & & & key_time ++;
if((key_time == 2)&&(key_cnt))
& & & & return 1;
else return 0;
mark,期待强大
mtlsh 发表于
我完全看不出来KeyRead()是如何执行两次才输出结果???
分时概念,仔细想想就知道。
zhaotyue 发表于
原本高大上的东西被你搞得如此不堪。
算不上高大尚,原程序把该处理的事情给省了,所以看起来简单,不消抖是其内伤。
embeddev_1
你这叫哪门子消抖!打回重做!{:titter:}
i7gly 发表于
这个仅是程序片断,没能看懂,能解释一下吗?
embeddev_1 发表于
你这叫哪门子消抖!打回重做!
不懂就别乱说,上面已经解释得很清楚,二次扫描值一致才确认按键。
rain73 发表于
分时概念,仔细想想就知道。
& & static u8 tmp, i=0;都是局部变量, 如何分时????
rain73 发表于
这个仅是程序片断,没能看懂,能解释一下吗?
利用延时的概念,上升沿复位计时,计时一定时间后判断按键,如果还在按下状态则返回按键值,不在状态不返回.
mtlsh 发表于
static u8 tmp, i=0;都是局部变量, 如何分时????
哦这个,其实那个i是全局变量来的,和KeyRead()内部的i名称重复了,为避免误解,KeyRead()内部的改名为ii。
看main()上面的变量定义就明白了。
foxpro2005
之前有个坛友已经分享了一个在原基础上增加消抖功能例程, 看过 还算比较不错的,你可以参考一下(自己搜一下)
i7gly 发表于
利用延时的概念,上升沿复位计时,计时一定时间后判断按键,如果还在按下状态则返回按键值,不在状态不返回. ...
明白了,原来是单键的程序。
上面的是多键的,一个口8位都可以处理。
rain73 发表于
明白了,原来是单键的程序。
上面的是多键的,一个口8位都可以处理。
我比较喜欢这样用
连续两次为1则为1,连续两次为0则为0,其他保持不变。
& & & & static uint32_t temp1 = 0;
& & & & static uint32_t temp2 = 0;
& & & & static uint32_t key_in = 0;
& & & & temp2 = temp1;
& & & & temp1 = READ_KEY();
& & & & key_in = (temp1&temp2) | (key_in&(temp1|temp2));
blxy 发表于
我比较喜欢这样用
连续两次为1则为1,连续两次为0则为0,其他保持不变。
temp1和temp2没有时间间隔?
越基本的东西 越考功力,值得研究
我发现你没有返回键值呀,你用全局变量 这个函数移值起来就不方便了。反复测试就知道了。
wind2100 发表于
我发现你没有返回键值呀,你用全局变量 这个函数移值起来就不方便了。反复测试就知道了。 ...
原贴的例子就是这样的。这里用到了分时结构,分时结构中全局变量是免不了的,而且也是多变量输出。
有兴趣可以自己研究下如何封装,不过我觉得没有多大必要。
rain73 发表于
temp1和temp2没有时间间隔?
temp1先赋值给temp2,然后再更新内容的,temp2是temp1上一次扫描的内容
blxy 发表于
temp1先赋值给temp2,然后再更新内容的,temp2是temp1上一次扫描的内容
嗯,这样不错,这倒启发了我,“异或”用来做跳变检测,“非异或”可以用来防抖。
那可以改成这样:
tmp1 = tmp2;
tmp2 = P1 ^ 0xFF;
if (tmp1 ^ tmp2)
也还可以再加一层防抖:
tmp3 = tmp1;
tmp2 = P1 ^ 0xFF;
if (tmp3 ^ tmp2)
这里,tmp1为上次值,tmp3为上上次值,tmp2为当前次值。
如此,多次采样也能简单实现,明天实际测试一下,如逻辑正确这样的防抖就更完美了!
mtlsh 发表于
static u8 tmp, i=0;都是局部变量, 如何分时????
static 是静态变量,,分配的内存是一值要保存的.
LZ可以看看我写的关于独立按键扫描的博文
http://blog.csdn.net/xuechaojie/article/details/6761772
我觉得 这10MS 消抖动的时间 要能调整才行,也就是说当按下的时间稳定的在50MS 才能算是短按,那么如果是10MS扫描一次得有5次才成功,会比较可靠。
或是说要能调整。
Eric_Xue 发表于
LZ可以看看我写的关于独立按键扫描的博文
http://blog.csdn.net/xuechaojie/article/details/6761772 ...
先拜读一下,回头再写读后感。
wind2100 发表于
我觉得 这10MS 消抖动的时间 要能调整才行,也就是说当按下的时间稳定的在50MS 才能算是短按,那么如果是10 ...
你看一下23楼,应该找到了简单多次采样的方法,要多少次采样都行,回头我测试正确再发布出来。
wind2100 发表于
我觉得 这10MS 消抖动的时间 要能调整才行,也就是说当按下的时间稳定的在50MS 才能算是短按,那么如果是10 ...
这是按键扫描的底层程序,每隔10ms采样一次,只消抖。
之所以以10ms为例,是因为10ms经常为RTOS的系统时钟中断间隔。只要系统每10ms调用keyscan()就可以了,用不用在按键扫描程序里面等待延迟。
不能把底层写的很复杂,比如实现长按、短按等功能,把这些留给上层程序去做。
Eric_Xue 发表于
这是按键扫描的底层程序,每隔10ms采样一次,只消抖。
之所以以10ms为例,是因为10ms经常为RTOS的系统时 ...
那底层 也应该有 按下(下降沿),弹起(上升沿) 吧
分层对软件来讲是一个有意思的东西,好的代码,一定分得很清晰。
那么 长按和多击 应该是在上一层了。
超过三行了。
wind2100 发表于
那底层 也应该有 按下(下降沿),弹起(上升沿) 吧
分层对软件来讲是一个有意思的东西,好的代码,一 ...
//按键变量
unsigned char& &KeyPressDown=0x00;
unsigned char& &KeyRelease=0x00;
unsigned char& &LastKey=0x00;
KeyPressDown用来记录按下
KeyRelease用来记录弹起。
lastkey用来记录按键(经过滤波后)的实际状态(低或高)。
Eric_Xue 发表于
LZ可以看看我写的关于独立按键扫描的博文
http://blog.csdn.net/xuechaojie/article/details/6761772 ...
读了你的博文,解释得很详细。核心算法是:
CurrKey=(CurrReadKey&LastReadKey)|LastKey&(CurrReadKey^LastReadKey)
结合以下真值表:
时 刻 & & & & CurrKey & & & & LastReadKey & & & & CurrReadKey
1 & & & & & & & & 0 & & & & & & & & 0 & & & & & & & & & & & & 0
2 & & & & & & & & 0 & & & & & & & & 0 & & & & & & & & & & & & 1
3 & & & & & & & & 0 & & & & & & & & 1 & & & & & & & & & & & & 0
4 & & & & & & & & 0 & & & & & & & & 0 & & & & & & & & & & & & 1
5 & & & & & & & & 1 & & & & & & & & 1 & & & & & & & & & & & & 1
6 & & & & & & & & 1 & & & & & & & & 1 & & & & & & & & & & & & 1
7 & & & & & & & & 1 & & & & & & & & 1 & & & & & & & & & & & & 0
8 & & & & & & & & 1 & & & & & & & & 0 & & & & & & & & & & & & 1
9 & & & & & & & & 1 & & & & & & & & 1 & & & & & & & & & & & & 0
10 & & & & & & & & 0 & & & & & & & & 0 & & & & & & & & & & & & 0
11 & & & & & & & & 0 & & & & & & & & 0 & & & & & & & & & & & & 0
总结起来就是:前后两次采样值相同则保存新值,不同则维持上次值(原值)。
这跟我23楼说的:“异或”用来做跳变检测,“非异或”可以用来防抖的思路是一样的。
这个算法是二次采样,我上面应该找到了突破二次采样变为多次采样的简单方法了。
wxtypeng 发表于
超过三行了。
你这是要计较万用表不万用。
人家讲的是核心算法三行而已。
一个小按键,搞的这么复杂
在大家的指导下,参考了多种消抖算法,终于总结出多次采样的程序,经测试成功。
这样,以三行核心算法为主导,可以识别压下(下降沿)、弹起(上升沿)、短按、长按、连发、多次采样消抖的程序基本完善,可以和状态机键盘媲美了。
#define TIMES& & & & & & & & & & & & 3& & & & & & & & & & & & //采样次数设定
#define READ_KEYPORT& & & & P1^0xFF& & & & & & & & //读键盘口
/* 2次采样 */
void KeyRead() {
& & & & static u8 Curr = 0;
& & & & static u8 L
& & & & Last = C
& & & & Curr = READ_KEYPORT;
& & & & if (Curr^Last)
& & & & TrgDown = Curr & (Curr ^ Prev);& & & & & & & & //Down跳变
& & & & TrgUp& &= Prev & (Curr ^ Prev);& & & & & & & & //Up跳变
& & & & Prev = C& & & & & & & & & & & & & & & & & & & & //前次值
/* TIMES+1次采样 */
void KeyRead() {
& & & & static u8 Curr = 0;
& & & & static u8 L
& & & & static u8 ii = 0;
& & & & if(ii==0)Last = C
& & & & while (ii & TIMES) {
& & & & & & & & Curr = READ_KEYPORT;
& & & & & & & & if (Curr^Last)& & & & { ii = 0; }
& & & & & & & & else& & & & & & & & & & & & { ii++;& & }
& & & & ii = 0;
& & & & TrgDown = Curr & (Curr ^ Prev);& & & & & & & & //Down跳变
& & & & TrgUp& &= Prev & (Curr ^ Prev);& & & & & & & & //Up跳变
& & & & Prev = C& & & & & & & & & & & & & & & & & & & & //前次值
程序分二种,如果只需要2次采样,则用第一种方式,简单明了。
如果需要多次采样,则用第二种方式,适用于任何干扰的场合,采样次数TIMES最大值255,也就是255*10ms=2.55s,一般4-5次采样足够了。
liupanliang
写的不错!赞一个
查看完整版本:红米手机 &
电视盒子 &
智能硬件 &
神马级手机控
楼主的荣誉
扫码下载App一键签到 升级加速
【虚拟按键】无需RE 简单几步开启虚拟按键!【原创】
&来自老版论坛
扫一扫!手机看帖更爽
虚拟按键开启方法!
& && && && && && && && && &-寂寞人颜
虚拟按键开启教程!(图文的{:2_37:})☆§☆§☆§☆§☆§☆§☆§☆§超强分割线§☆§☆§☆§☆§☆§☆§☆§☆
感觉别人手机上的虚拟按键怎么样?想不想要?
☆§☆§☆§☆§☆§☆§☆§☆§超强分割线§☆§☆§☆§☆§☆§☆§☆§☆
简单!跟我来!简单几步让你拥有强大的虚拟按键!
(告诉你个小秘密:如果屏幕下的三个按键坏了,又不想修,就用它吧!很强大!)
☆§☆§☆§☆§☆§☆§☆§☆§超强分割线§☆§☆§☆§☆§☆§☆§☆§☆
如果你用过修改文件开启虚拟按键的方法!那就更需要来看看了!
(此教程纯属小白版!高手勿喷!)
以前,开启虚拟按键需要ROOT,需要RE管理器,还要懂代码!太J8麻烦了!(爆粗口了!..)
以下内容被隐藏,回复本帖后可见
☆§☆§☆§☆§☆§☆§☆§☆§超强分割线§☆§☆§☆§☆§☆§☆§☆§☆
还有很多有趣的东西!多多尝试吧!
扫描二维码,手机查看本帖
·来自老版论坛
小手一抖,积分全有!··········小手一抖,积分全有!············ ··
·来自老版论坛
先谢谢楼主了!回复看看,有什么给力的地方
·来自老版论坛
既然有这个东东,那就学习一下吧
·来自老版论坛
很不错的软件,大家可以试试看o& &
·来自老版论坛
想看看,真心实用吗?
·来自老版论坛
好东西当然要赶紧收起了啦啦啦啦啦
·来自老版论坛
:o哈哈哈哈哈好东西哦& &&&支持
·来自老版论坛
uoghifguyfutgf答复意见和规范员工费用官方
·来自老版论坛
如何搞呢???qiujie ```
·来自老版论坛
intent:#IS.K_=;end
dddddddddddddddddddddddddddddddd#dddddddddddddddddddd
·来自老版论坛
intent:#IS.K_=;end
·来自老版论坛
dDddddddsssssddddddghjjjjdsXvbghhhhhhhhhhhhhhhhhhhhhhh
·来自老版论坛
ddddddddddddddddddddddddpdddddddddddddddddddddddddddddd
·来自老版论坛
这个可以有 试试看 {:1_1:}
·来自老版论坛
无需RE 简单几步开启虚拟按键
·来自老版论坛
好东西好东西好东西好东西
·来自老版论坛
小米的實體沒有燈
早就想換了
·来自老版论坛
看看看看看看看看看看看看看看看看是什么啊????????
·来自老版论坛
真的好技巧,学习学习了!
·来自老版论坛
这个我有印象,虽然用不到,但还是感谢分享
京ICP证110507号 京ICP备号快捷键_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
上传于||暂无简介
阅读已结束,如果下载本文需要使用1下载券
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩2页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢

我要回帖

更多关于 方太em03t按键说明 的文章

 

随机推荐