ppt中怎么编辑ppt个人简历制作

|  
|  
|  
|  
|  
只需一步,快速开始
查看: 6904|回复: 55
不知道大家还记不记得有款叫做《全境封锁》的游戏……
主题帖子积分
高级玩家, 积分 309, 距离下一级还需 291 积分
高级玩家, 积分 309, 距离下一级还需 291 积分
好吧,我说错了,是《全境缩水》……当初E3试玩视频是那样的高大上,结果实际就呵呵了。反正我是被育碧坑惨了……幽灵行动……等正式发售后3个月再说吧……不想再被育碧坑了……
主题帖子积分
游戏精英, 积分 5133, 距离下一级还需 3867 积分
游戏精英, 积分 5133, 距离下一级还需 3867 积分
看门狗不缩水1080都搞不定 请问你用那块显卡跑 泰坦2吗 用的渣卡还吐槽所谓锁水 你去玩游戏机啊 离屏幕远点你也看不出缩水对吧
主题帖子积分
高级玩家, 积分 309, 距离下一级还需 291 积分
高级玩家, 积分 309, 距离下一级还需 291 积分
看门狗不缩水1080都搞不定 请问你用那块显卡跑 泰坦2吗 用的渣卡还吐槽所谓锁水 你去玩游戏机啊 离屏幕远点 ...
除了骂人你还会说啥?看门狗我没玩过没有发言权,但是全境封锁我没吐槽画面缩水吧,我说的是内容缩水好不。再说,你咋不说育碧优化差呢。
主题帖子积分
獨角獸傭兵團團長
游戏达人, 积分 2511, 距离下一级还需 989 积分
游戏达人, 积分 2511, 距离下一级还需 989 积分
除了骂人你还会说啥?看门狗我没玩过没有发言权,但是全境封锁我没吐槽画面缩水吧,我说的是内容缩水好不 ...
讲道理,,,别人没骂人。。。
主题帖子积分
游戏狂人, 积分 1409, 距离下一级还需 591 积分
游戏狂人, 积分 1409, 距离下一级还需 591 积分
<font color="#youxi 发表于
除了骂人你还会说啥?看门狗我没玩过没有发言权,但是全境封锁我没吐槽画面缩水吧,我说的是内容缩水好不 ...
真不知,你哪只眼睛看到人家骂人了
主题帖子积分
高级玩家, 积分 352, 距离下一级还需 248 积分
高级玩家, 积分 352, 距离下一级还需 248 积分
全境封锁更新1.5版本,现在起死回生了啊
各种匹配从来没超过1分钟
主题帖子积分
游戏狂人, 积分 1296, 距离下一级还需 704 积分
游戏狂人, 积分 1296, 距离下一级还需 704 积分
内容缩水是为了卖DLC,
主题帖子积分
云游中.....
贡献度1830
金元262929
我对新版本的BUG还是有怨念的
主题帖子积分
游戏精英, 积分 5133, 距离下一级还需 3867 积分
游戏精英, 积分 5133, 距离下一级还需 3867 积分
你光买本体就别题啥内容缩水
主题帖子积分
游戏狂人, 积分 1803, 距离下一级还需 197 积分
游戏狂人, 积分 1803, 距离下一级还需 197 积分
全境封锁现在很火啊,1.4更新之后外加各种DLC轰炸,除了土豆服务器人气现在已经大幅回复,口碑也变好了,
TheDivision__23_28_14_534.jpg (180.39 KB, 下载次数: 1)
19:44 上传
最后对于雪天的描写我觉得是目前游戏中最真实的,目前游戏的优化也很赞,如果真按照当年E3展那水平,就和巫师3当年的那个预告一样,谁的电脑能跑动?
主题帖子积分
超级玩家, 积分 747, 距离下一级还需 253 积分
超级玩家, 积分 747, 距离下一级还需 253 积分
樓主說的說水應該是地圖,當初UBI給人的感覺是涵蓋整個紐約,結果遊戲只出現曼哈頓
主题帖子积分
游戏狂人, 积分 1948, 距离下一级还需 52 积分
游戏狂人, 积分 1948, 距离下一级还需 52 积分
不管怎么说,无缝丛林地图已成为育碧的长项
主题帖子积分
游戏精英, 积分 4953, 距离下一级还需 4047 积分
游戏精英, 积分 4953, 距离下一级还需 4047 积分
。。。继续全境。。。。。。荒野这射击视角转换和风格太诡异了。。。。。。。作为大菠萝3的TPS版我觉得还是很不错的。。。。。。
主题帖子积分
游戏精英, 积分 3869, 距离下一级还需 5131 积分
游戏精英, 积分 3869, 距离下一级还需 5131 积分
全境封锁现在很火啊,1.4更新之后外加各种DLC轰炸,除了土豆服务器人气现在已经大幅回复,口碑也变好了,
火个鸡吧,一个网游在线1W人就多了?下雪真实?从开服一直下到现在也是笑死人了。不过脑残粉很给力了最近的评价刷到多半好评,可惜整体评价还是一半的差评
主题帖子积分
游戏精英, 积分 4485, 距离下一级还需 4515 积分
游戏精英, 积分 4485, 距离下一级还需 4515 积分
全境我记得 我是预购玩家
QQ截图40.png (208.51 KB, 下载次数: 0)
15:50 上传
最后我还是买了
QQ截图05.png (13.69 KB, 下载次数: 0)
15:53 上传
我对育碧的游戏是又爱又恨的 每次被坑玩 一出宣传片看完就很想买
主题帖子积分
高级玩家, 积分 595, 距离下一级还需 5 积分
高级玩家, 积分 595, 距离下一级还需 5 积分
就怕育碧喜欢上你们这点。。。。。再说这次幽灵行动,b测那块地虽然不是全图,但也还是不小,要是游戏内容真的就是这些*10我估计又得有人崩溃
主题帖子积分
游戏精英, 积分 3566, 距离下一级还需 5434 积分
游戏精英, 积分 3566, 距离下一级还需 5434 积分
缩水狗+全境狂缩,2次教训真儿真儿的够了。以后玉逼的游戏有盗版就玩盗版,没有就拉倒,绝不入正。
主题帖子积分
高级玩家, 积分 273, 距离下一级还需 327 积分
高级玩家, 积分 273, 距离下一级还需 327 积分
其实画质缩水我觉得更多的是为了照顾大家的电脑可以流畅的运行即便你有4路ttxp,也不能保证所有人都有吧~ 特别是保有量最大的甜品级显卡,960啦,1060等等只有大多数人能流畅的玩耍大家才会去买啊~ 每次出一个游戏换一张旗舰卡一般人都是受不了的好伐,而且我也是全境封锁的玩家,对于全境我想吐槽的只是那刷刷刷的游戏模式
主题帖子积分
超级玩家, 积分 930, 距离下一级还需 70 积分
超级玩家, 积分 930, 距离下一级还需 70 积分
缩水就缩水了,关我PIS,全境封锁真TM好玩
主题帖子积分
中级玩家, 积分 228, 距离下一级还需 22 积分
中级玩家, 积分 228, 距离下一级还需 22 积分
我觉得看门狗真心一般&&比不上GTA&&买了有点后悔& &英雄连2和战地1战地4是我买的最值得游戏
主题帖子积分
游戏狂人, 积分 1888, 距离下一级还需 112 积分
游戏狂人, 积分 1888, 距离下一级还需 112 积分
全境我已经被封了~~~
主题帖子积分
超级玩家, 积分 676, 距离下一级还需 324 积分
超级玩家, 积分 676, 距离下一级还需 324 积分
全境的画质真没什么可黑的。主要是被外挂毁掉了。不知楼主所谓的缩水是指什么?如果荒野的品质和全境一样,那足可以值回票价,唯一可滤的,就是外挂了。
主题帖子积分
高级玩家, 积分 276, 距离下一级还需 324 积分
高级玩家, 积分 276, 距离下一级还需 324 积分
前期原力战士太狠了,导致我粉转黑,但是地下世界开始,我又黑转粉了,真个世界观不错,可惜的是载具不能开。
主题帖子积分
高级玩家, 积分 276, 距离下一级还需 324 积分
高级玩家, 积分 276, 距离下一级还需 324 积分
全境的画质真没什么可黑的。主要是被外挂毁掉了。不知楼主所谓的缩水是指什么?如果荒野的品质和全境一样, ...
这种纯PVE向的,外挂的问题不大吧,基佬组队就好。
主题帖子积分
高级玩家, 积分 396, 距离下一级还需 204 积分
高级玩家, 积分 396, 距离下一级还需 204 积分
讲道理全境还是值得那个价格的。。。起码刷了很久后期也是pve没有提升了打黑街被外挂花式吊打才弃的。。
主题帖子积分
高级玩家, 积分 396, 距离下一级还需 204 积分
高级玩家, 积分 396, 距离下一级还需 204 积分
讲道理全境还是值得那个价格的。。。起码刷了很久后期也是pve没有提升了打黑街被外挂花式吊打才弃的。。
主题帖子积分
新手玩家, 积分 20, 距离下一级还需 10 积分
新手玩家, 积分 20, 距离下一级还需 10 积分
爱玩玩不玩滚 真JB难伺候 论游戏创新 数量 品质 全方位考量除了育碧没什么太良心的了 偶尔雷作又能怎样 不也尽力修复了么 比某空天天冷饭好不容易憋出个续作硬拆游戏内容当DLC卖强太多了
主题帖子积分
高级玩家, 积分 276, 距离下一级还需 324 积分
高级玩家, 积分 276, 距离下一级还需 324 积分
全境还好,如果能自由选择私人暗区,同时又提高公共暗区收益,我觉得还能再回一波血。
主题帖子积分
高级玩家, 积分 447, 距离下一级还需 153 积分
高级玩家, 积分 447, 距离下一级还需 153 积分
你们这些喷的脑残& && & 玩过现在的全境封锁么 就瞎喷& & 育碧的游戏是在不断优化的好么& &&&有这么多创新的公司&&就算做不好客服 做不好服务器& &但优化在那啊& && &&&再说哪个游戏刚发售没个bug& & 逮到一个事来回说有意思么& &shab& &
主题帖子积分
游戏狂人, 积分 1803, 距离下一级还需 197 积分
游戏狂人, 积分 1803, 距离下一级还需 197 积分
本帖最后由 翼神传说 于
20:16 编辑
火个鸡吧,一个网游在线1W人就多了?下雪真实?从开服一直下到现在也是笑死人了。不过脑残粉很给力了最近 ...
本来不想回你的,但是最近翻帖子看到了你这个回复,还是要反驳一下。
首先全境封锁每日平均在线人数确实有一万左右,但是对于这种本体卖钱DLC卖钱的网游来说算是不错了,还有游戏品质不能单纯看在线人数,CF峰值在线人数八百多万,就算是正当红的DOTA2和LOL以及老牌神作魔兽世界在CF面前都得跪舔,你能说CF游戏品质高过以上三个游戏吗,全境封锁至少官方在一次次更新完善它,1.5之后游戏各方面都很良心,至少已经花钱买了这游戏的玩家不会失望。
下雪效果不真实?呵呵,你给我找一个对于雪天描写比全境封锁更加真实的游戏拿出来我看看。
59_1.jpg (153.64 KB, 下载次数: 0)
20:06 上传
23_1.jpg (242.06 KB, 下载次数: 0)
20:05 上传
16_1.jpg (183.41 KB, 下载次数: 0)
20:05 上传
最后steam现在是多数好评,少数差评百分之90也是因为服务器问题。
当然,没有玩过就没有资格评价,请你晒出你的steam库
潜行的混沌
3DM页游玩家
3DM页游玩家专属,沉迷于页游中不可自拔,堕落的3DM勋章
3DM女性会员专属勋章
3DM众聚夺宝活动
3DM死忠专属勋章
实干版主勋章
版主任职6个月以上,长期坚守所在版区,坚持内容更新、日常维护、任劳任怨
论坛热心人士
注册时间3个月以上,发帖量高于1000,且在最近3个月内,于论坛中积极活跃,热心解答会员各种疑难问题,并获得版主认可
大型活动中大奖两次以上
官方群水友
加入由论坛管理员在各种活动中指定的官方群即可获得,退群可能会被撤销哦
Powered by题目:多功能按键设计。利用一个I/O口,接一个按键,实现3功能操作:单击 + 双击 + 长按。
回复【96楼】packer&&
回复【95楼】ufbycd
-----------------------------------------------------------------------
这么打个比方,有个项目招标,为了可维护性和可扩展性,我需要用16krom的芯片,价格20元。而放弃可维护性和可扩展性可以用8k芯片,价格10元。(仅仅是个比方)
这时候你说我应该把谁放第一位?
而在项目资源足够的情况下,我不考虑可维护性和可扩展性,只能说我弱智。
所以在我看来,一切前提是完成项目。可能是在严酷的市场竞争中拼打多年,变的太现实了。
再回顾 81楼
-----------------------------------------------------------------------
igoal:这也就是我想讲的,下面一层的代码不要帮助上层的代码做本来属于上层代码的工作,否则就破坏了代码的分层机制
-----------------------------------------------------------------------
你选8K芯片并不代表没有任何维护性和扩展性。
只要你稍微考虑一下函数如何拆分、什么函数应该实现什么功能就会提高维护性和扩展性。
代码承载了两部分作用:实现功能和被人维护,也就是代码的功能和代码的质量。
不应过分追求代码的功能也不应过分地追求代码的质量,而应取折中,两手都要抓、两手都要硬,不偏废彼此。
Do one thing, and do it well!是最重要的思想,但实现起来一点都不难,也不会耗费过多的资源,只要多考虑下函数是什么层就行了
用过 MVC 设计模式的人就会知道,前期为了实现MVC进度会比不用设计模式的要慢点,但它的扩展性非常强,以后添加什么或需求有什么
变化都是非常容易实现的。
就如同《笑傲江湖》里所说的,“剑宗与气宗的区别”:
“剑宗功夫易於速成,见效极快。大家都练十年,定是剑宗占上风;各练二十年,那是各擅胜场,难分上下;要到二十年之后,练气宗功夫的才渐渐的越来越强;到得三十年时,练剑宗功夫的便再也不能望气宗之项背了。”
回复【楼主位】machao
题目:多功能按键设计。利用一个i/o口,接一个按键,实现3功能操作:单击 + 双击 + 长按。& &
============================================================================&&
& && &&&else if (++key_time &= 100)& &&&// 继续按下,计时加10ms(10ms为本函数循环执行间隔)&&
& && &&&{&&
& && && && & key_return = L_& && &&&// 按下时间&1000ms,此按键为长按操作,返回长键事件&&
& && && && & key_state = key_state_3;& &// 转换到等待按键释放状态&&
& && &&&}&&
& && &&&&&
-----------------------------------------------------------------------
& && &&&else if (++key_time &= 100)& &&&//是不是应该将key_time置回0哈?!不然一次长按后,都成长按了~~~~
& && &&&{&&
& && && && & key_return = L_& && &&&
& && && && & key_state = key_state_3;& &
& && && && && && && && && && && && && & //Key_time = 0;& &
& && &&&}&&
回复【101楼】popwolf
-----------------------------------------------------------------------
不用。仔细分析第一层状态图,state3只能回到state0,而state0唯一的出路是去state1,所以在state1清time就行
回复【61楼】eduhf_123 经历
回复【32楼】machao& &
-----------------------------------------------------------------------
--------------------------------------------------------------------------------
给马老师纠个错,这里的key_time是全局非静态变量(因为没有加static修饰符,全局可见),如果一定要认为static与auto两个存储类别互斥,那么它就是个“全局自动变量”。
----------------------------
此时key_time确实是 全局静态变量 ;因为此时key_time具有文件作用域,对于文件作用域,static只表明内部链接,因此无论前面有无static,都具有静态存储时期...
关于上个帖子中马老师出的题目,抽空做了一下,是在多键(低电平和阵列扫描2种)下做的,本来想交作业的。。。
看完马老师这贴,看起来还是有些漏洞,有些繁复了。。。下决心重做了。。。
学不可以已!!!
回复【108楼】popwolf
回复【61楼】eduhf_123 经历
回复【32楼】machao& &
-----------------------------------------------------------------------&&
--------------------------------------------------------------------------------
给马老师纠个错,这里的key_time是全局非静态变量(因为没有加static修饰符,全局可见),如果一定要认为static与auto两个存储类别互斥,那么它就是个“全局自动变量”。&&
----------------------------
此时key_time确实是 全局静态变量 ;因为此时key_time具有文件作用域,对于文件作用域,static只表明内部链接,因此无论前面有无stat......
-----------------------------------------------------------------------
eduhf_123 经历的解释是可以的,他考虑到的是更大范围:多个文件是否可以使用key_time变量。
如果只考虑本文件的范围,key_time 就可以简单的认为是全局静态变量,
如果考虑是多文本的范围,那么key_time的定义还可以分成2种:
(1)&&static unsigned char key_ (2)auto unsigned char key_----注意,通常auto是省掉的。
前者表示此变量只能在本文中使用,称做:全局外部静态变量
后者表示此变量允许其它文件使用,称做:全局外部非静态变量,或简称全局外部变量
这里的“静态”和“非静态”不是表示它的存储方式和位置,是表示变量的存在时间。
那么在内存中静态存储区中分配的变量是静态存储型变量,静态存储型变量是整个程序运行时间都存在的,不会释放掉。三种变量将定义分配在这个区域:
1。局部静态变量(在一个函数内部用static定义的变量)
2。全局外部静态变量(在本文件中,定义在函数外部的,用static声明的变量)
3。全局外部非静态变量(在本文件中,定义在函数外部的,用auto声明的变量)
这里我们看到,全局外部静态变量和全局外部非静态变量都是“静态”分配存储的变量。而名称中静态则表示的是该变量的存在时间,“静态”表示有时间限制,“非静态”表示无时间限制。
从存储角度,“静态”的另一面是“动态”;从存在时间角度,“静态”的另一面是“非静态”。
因此在名称上容易使人混淆,重要的是当看到一个变量的定义,要能马上知道它的含义和特点:比如什么时间分配内存,什么时间赋初值,在什么地方可以使用等。
记得N年前,曾使用教课书上这样的例题作为测试,回答的正确率不高:
int a=3,b=5;
& &c=a&b?a:b;
& &return (c);
& &int a=8;
& &printf(&%d&,max(a,b));
问运行结果是什么?
按照这种方式在单片机上实验按键的单击、双击和长按没能通过,总提示没有按键按下,即使按了键也显示没有键按下。不知道哪位大神在单片机上将这种方式实验成功过?还是这种方式不适合单片机?
有仿真器吗,单步走,看看每步寄存器输出是否符合设计要求。还有你硬件怎么接的,把资料发上来看看。
这个方法绝对适合单片机。
当然,我没实际验证,仅通过读程序没发现明显逻辑问题。
回复【114楼】packer&&
-----------------------------------------------------------------------
我用的STM32单片机,按键电路图如图1
图1.按键图 (原文件名:11.gif)
/* filename: usart.c */
#include &STM32f10x.h&
#include &key.h&
#define key_input& & GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2)& & // 按键输入口
#define N_key& & 0& && && && & //无键&&
#define S_key& & 1& && && && & //单键&&
#define D_key& & 2& && && && & //双键&&
#define L_key& & 3& && && && & //长键&&
#define key_state_0 0&&
#define key_state_1 1&&
#define key_state_2 2&&
#define key_state_3 3
void KEY_PIN_INIT(void)
&&GPIO_InitTypeDef GPIO_InitS
&&//使能按键的时钟
&&RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
&&//配置按键为浮空输入
&&GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
&&GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
&&GPIO_Init(GPIOC, &GPIO_InitStructure);
u8 key_driver(void)
&&static u8 key_state = key_state_0,key_time = 0;
&&u8 key_press,key_
&&key_press = key_
&&switch(key_state)
&&case key_state_0:
& & if(!key_press)
& && & key_state = key_state_1;
&&case key_state_1:
& & if(key_press)
& && &key_time = 0;
& && &key_state = key_state_2;
& && &key_state = key_state_0;
&&case key_state_2:&&
& & if(key_press)&&
& && & key_return = S_& && && &
& && & key_state = key_state_0;& &&&
& & else if (++key_time &= 100)& && &
& && & key_return = L_& && && &
& && & key_state = key_state_3;& &&&
&&case key_state_3:
& & if(key_press)
& && &key_state = key_state_0;
&&return key_
u8 key_read(void)
&&static u8 key_m = key_state_0, key_time_1 = 0;&&
&&u8 key_return = N_key,key_&&
&&key_temp = key_driver();&&
& & switch(key_m)&&
& && &&&case key_state_0:&&
& && && && &if (key_temp == S_key )&&
& && && && &{&&
& && && && &&&key_time_1 = 0;& &
& && && && &&&key_m = key_state_1;&&
& && && && &}&&
& && && && &else
& && && && &{
& && && && &&&key_return = key_
& && && && &}
& && && && &&&
& && &&&case key_state_1:&&
& && && && &if (key_temp == S_key)& && && && & // 又一次单击(间隔肯定&500ms)&&
& && && && &{&&
& && && && && &&&key_return = D_& && && &&&// 返回双击键事件,回初始状态&&
& && && && && &&&key_m = key_state_0;&&
& && && && &}&&
& && && && &else& && && && && && && && && && && &
& && && && &{& && && && && && && && && && && & // 这里500ms内肯定读到的都是无键事件,因为长键&1000ms,在1s前低层返回的都是无键&&
& && && && && &&&if(++key_time_1 &= 50)&&
& && && && && &&&{&&
& && && && && && && & key_return = S_& && &// 500ms内没有再次出现单键事件,返回上一次的单键事件&&
& && && && && && && & key_m = key_state_0;& &&&// 返回初始状态&&
& && && && && &&&}&&
& && && && & }&&
& && && && &&&
& & return key_
第一个函数是配置PC2为浮空输入,用于读取按键的电平,下面两个函数就是一样的。
主函数中调用
& &&&if(user_key_time==0)
& && & key_value = key_read();
& && & switch(key_value)
& && && & case 0:
& && && && &USART1_Puts(&没有键盘按下的消息&);
& && && && &USART1_Putc(0x0D);USART1_Putc(0x0A);
& && && &&&
& && && & case 1:
& && && && &USART1_Puts(&单击键盘按下的消息&);
& && && && &USART1_Putc(0x0D);USART1_Putc(0x0A);
& && && & case 2:
& && && && &USART1_Puts(&双击键盘按下的消息&);
& && && && &USART1_Putc(0x0D);USART1_Putc(0x0A);
& && && & case 3:
& && && && &USART1_Puts(&长按键盘按下的消息&);
& && && && &USART1_Putc(0x0D);USART1_Putc(0x0A);
& && &&&default:
用串口显示是单键,双键还是长按还是没有键盘按下,目前是无论是否按键都提示没有键盘按下。
回复【114楼】packer&&
-----------------------------------------------------------------------
我用IAR软件单步调试的,key_read()的返回值永远是0.
都建议你单步调,怎么上来只说key_read()的返回值。要从根查起。
u8 key_driver(void)
&&key_press = key_
看过按键按下时,key_driver里的key_press值是否正确?如果IO电平都没读对,何谈后面的。
又花了一个小时,原来我定时器时间设置错了,10ms搞成了10s,我单步跟踪总是返回零,改过来就好了。谢谢packer的批评与指正。
STM32上面单键实现单击、双击和长按串口输出显示图 (原文件名:11.gif)
马老师的题目非常明确:多功能按键设计。利用一个I/O口,接一个按键,实现3功能操作:单击 + 双击 + 长按。
隐含条件就是在普通的8位单片机上能够实现的。方法也告诉大家了:用状态机。并且也给出了一个实用的程序。
所以大家应该按马老师的要求尽量多做(使之能用在自己所用的单片机上,或者修改程序使之更完美、更通用)。
不要去瞎争辩,比如去和手机等带OS的比,更不要去和MS或者windows去比,不是一个数量级的,比到最后你会发现这么简单的功能无法在单片机中实现,哈哈。
争辩的焦点主要在双击如何实现上。
下面我给一个图,比程序状态图应该更容易看,应该对如何判断双击有帮助。
(原文件名:按键分类.jpg)
楼上最好解释下你的图,什么是单击,什么是短击。长击后为什么还要跟个连击。另外你的双击是怎么实现的我实在是看不懂。
只是一个按键状态图,你的按键再怎么按,也逃不出我的这个按键状态图。
然后你想用按键的什么状态,就随便了。
由图中可以看出,双击是由两个单击(或短击)组合的,所以在程序上判断必须比读键值程序高一层才能实现。
单击和短击:一次短暂的按键,按下就反应曰“单击”,松开才反应曰“短击”。
长击:& && &就是长按,一直按着到了规定时间,发出长击码。
连击:& && &也是长按的一种,一直按着,就不停的发出连击码。
都是可选的,用不着就忽略不发码,在程序上就是没有这个状态。
mark!自己先考虑好了再对比下答案
在图上还能看出,即使是在双击判断过程中,单击和短击也是可以用的,但是你要考虑到不至于引起冲突。
“单击和短击:一次短暂的按键,按下就反应曰“单击”,松开才反应曰“短击”。”不好意思,头一回听说这么个解释方法,孤陋寡闻了。
“由图中可以看出,双击是由两个单击(或短击)组合的,所以在程序上判断必须比读键值程序高一层才能实现”,又不好意思,实在在你的图上看不出程序是怎么分层的。
另外,如果你仔细看看我还有ifree64与马老师、packer讨论的是什么你就该清楚马老师的想法就是把你所说的“高一层”程序放到下面一层来,直接给出“是不是单击?是不是双击?是不是连按?”尽量减少分层,而我和ifree64都不同意这么做,我们希望由更高层次的代码完成这个判断工作,所以才出了这么多长篇大论。
“长击:& && &就是长按,一直按着到了规定时间,发出长击码。
连击:& && &也是长按的一种,一直按着,就不停的发出连击码”,搞不懂有了长击,连击还有必要吗?这么做程序不是更复杂?你不停的发长击码不就行了?
我来说说我的理解
(原文件名:2种按键消息.JPG)
注意,第一种我用了中间输出。
两种方法的优缺点
优点:如果仅有单击,或单击和双击有逻辑延续(严格讲应是双击时允许先出现单击反应),那么单击可以及时响应。
缺点:如果双击前不许出现单击响应,要增加额外处理(代价)。第一次单击时不处理,启动一个定时器,当双击时限到时再处理。
优点:上层程序直接用,不用考虑单击和双击的逻辑性。
缺点:所有单击按键有延时。
我非常感谢马老师出的这个题。当刚做这题时,我给的答案和马老师一样。而在后面的讨论中,才发现对于不同应用,应该有更多不同的处理方法。
还是那句话,打下良好基础,灵活应用。
wk,画个图大家说了这么多话,先re再看
回【126楼】 packer
其实你的第一种方法中的:“额外处理(代价)”,在第二种方法中也是有的:“所有单击按键有延时”,这两种代价的结果是一样的,都是最后造成了延时,不过是引起这种延时的代码所处的层次不一样罢了。
回复【125楼】igoal
“单击和短击:一次短暂的按键,按下就反应曰“单击”,松开才反应曰“短击”。”不好意思,头一回听说这么个解释方法,孤陋寡闻了。
-----------------------------------------------------------------------
我15年前做遥控器客户的规格书就这么要求的。
另外,如果你仔细看看我还有ifree64与马老师、packer讨论的是什么你就该清楚马老师的想法就是把你所说的“高一层”程序放到下面一层来,直接给出“是不是单击?是不是双击?是不是连按?”尽量减少分层,而我和ifree64都不同意这么做,我们希望由更高层次的代码完成这个判断工作,所以才出了这么多长篇大论。
-----------------------------------------------------------------------
哈哈,我觉得啊,其实马老师不是尽量减少分层,而是这么小的东西没必要分那么细。当初马老师出题也是觉得现在的人太浮躁,基础太差,有感而发。
搞不懂有了长击,连击还有必要吗?这么做程序不是更复杂?你不停的发长击码......
-----------------------------------------------------------------------
调时钟长用的方法之一。第一次单击,时间+1,长按不放一定时间后,时间+10变化。
注意,119楼长击后面叫连击,不是一个概念。
“单击”,“短击”的说法我确实第一次听到
另外我的说法是可以用长击码代替连击码。
回复【130楼】igoal
“单击”,“短击”的说法我确实第一次听到
另外我的说法是可以用长击码代替连击码。
-----------------------------------------------------------------------
sigh,我说毛-泽_东你知道是谁,我说毛润之你就不知道了?名称而已,我都没注意到他用“单击”“短击”,但我一看图就理解他想表达什么。
长击能不能代替连击要看应用了,肯定不是一定的。
我其实并不想咬文嚼字,不过对于我这种没听过“单击”,“短击”说法的人来说这个“击”字我的理解就是按键被按下的意思。所以无论是“单击”也好“短击”也罢,从字面上确实分不清哪个是按下反映哪个是抬起反映。
另外“长击能不能代替连击要看应用”这个我同意,毕竟应用领域千差万别,不能说长击就一定能代替连击,只是我还没有发现两者的区别罢了。
回复【132楼】igoal
-----------------------------------------------------------------------
呵呵,其实要不是你说,我都没注意他用的什么词。只是看了图,明白他要表达的意思。
另外,关于长按,我说个曾做过项目要求。用1个键调某个范围巨大的数。
一按下按键,数字加1;
继续长按2秒后,以3次/1秒速度数字加1;
继续长按5秒后,以10次/1秒速度数字加1;
继续长按5秒后,以3次/1秒速度数字加10.
把按键状态分得这么细可不止我一个,我也是跟“程序匠人”学的。
你怎么按,再加上按的时间长短,就构成了按键的不同状态,用读键程序来读,就是不同的键值。
键值分的细,有利于高一层的程序处理,只用switch case 跳转 或 if 判断即可。
马老师的程序,如果算上main 应该是三层:底层读键,中间层处理双击,顶层是键值应用。一般的说,中间层和顶层可以合在一起。马老师的也没错,通过分层,把程序写的非常清楚,好让不太会写按键程序的学生明白。因为我看到就不止一个学生要求马老师写具体程序了,实际上这个程序很多初学者就缺少一个细节分析。
状态机,我跟傻孩子学的,我也是马老师的学生。状态表的形式可不一定仅仅是状态编号,计时器的值也表明一定的状态,比如119楼我的图上,长击、连击都是看计时器的值是多少,转换成不同的键值的。
134楼,packer,能得到你的认可,谢谢!
马老师有空给我评点一下,看我是否学到家了,谢谢!
我又来捣乱了,从zhanan 的图中还真看不到按键状态分的有多细,因为连击之后只要一直按着键发出的都是连击事件,这种做法并没有比只发长按键有什么根本上的改变,至少在这个帖子中的所有讨论都看不出这种做法的优势。
另外回复【134楼】 packer
一按下按键,数字加1;
继续长按2秒后,以3次/1秒速度数字加1;
继续长按5秒后,以10次/1秒速度数字加1;
继续长按5秒后,以3次/1秒速度数字加10
这种做法只有一个长按状态也是可以实现的,并不比用长按+连击的状态复杂多少。倒是在长按后还要多出个连击状态,程序还要在长按后开定时器判断是不是有连击事件发生,如果有连击发生还要处理“连击”到“无键”这个状态的切换。比只处理“长按”到“无键”的状态切换又多了一次处理。
大家正常讨论,何来捣乱一说。
我感觉我们的分歧在任务如何划分上。
像上例,我是分成 单击,长按,连击1,连击2 (不要纠结于名字啦)四个状态。
而你只在本层出长按一种状态,在上层再细分。是不是这样?
另外,我为什么要处理“连击”或“长按”到无键状态?不理解
回【138楼】 packer
确实如你所说,我们的分歧在任务如何划分上,当然这个仁者见仁智者见智了,也没什么好讨论了,“连击”或“长按”到无键状态,其实也是涉及到任务分层上,按我的分层方式,“连击”或“长按”发生后是要切换到无键状态,才能继续工作的,不然下一次的单击或者双击操作发生时就没法判断,可以参见我在【48楼】画的图,但是你说你的做法不需要这种切换,这个我也不是很理解,如果没有无键这个状态的话,那按键就只能在双击,单击,长按三种状态间转换,如一开始就没按键呢?按键处于什么状态呢?
Mark先,有空再看。
回复【139楼】igoal
-----------------------------------------------------------------------
明白你的意思了。是要到无键。
马老师讲的很实在,中国就是缺少像马老师这样踏踏实实做事的人。
回复【139楼】igoal
-----------------------------------------------------------------------
你是否把简单问题复杂化了。
按照马老师的题目,实现3种功能:单击+双击+长按。(这里的单击实际上是指短击,无键状态是隐含的,因为没有任务处理所以不把它作为一种功能)
因为要判断双击,所以松开按键后要作一个判断:第一次松开还是第二次松开。在双击时限内第二次松开,这个肯定是双击了。
第一次松开后没有再按键,超过双击时限,那么要作为一次短击处理。不论是双击处理还是短击处理,完了都回到无键状态
看我的图,按键状态可以分得很细,但不一定全都用上。
在这个题目里实际只用了短击+长按,然后两次短击又生出一个双击。
短击会吧,长按也不难吧,这两个都是在底层直接取得键值。那么就剩下双击了:第一次取得底层的短击键值,先扣着不放,然后启动双击计时器。若超时,说明没有第二次按键,就把扣着的那个短击键值放出来。若又来一个短击键值,并且在双击时限内,显然这是一个标准的双击了,给出双击键值。
回复【137楼】igoal
我又来捣乱了,从zhanan 的图中还真看不到按键状态分的有多细,因为连击之后只要一直按着键发出的都是连击事件,这种做法并没有比只发长按键有什么根本上的改变,至少在这个帖子中的所有讨论都看不出这种做法的优势。
另外回复【134楼】 packer&&
一按下按键,数字加1;&&
继续长按2秒后,以3次/1秒速度数字加1;&&
继续长按5秒后,以10次/1秒速度数字加1;&&
继续长按5秒后,以3次/1秒速度数字加10
这种做法只有一个长按状态也是可以实现的,并不比用长按+连击的状态复杂多少。倒是在长按后还要多出个连击状态,程序还要在长按后开定时器判断是不是有连击事件发生,如果有连击发生还要处理“连击”到“无键”这个状态的切换。比只处理“长按”到“无键”的状态切换又多了一次处理。
-----------------------------------------------------------------------
单键的连_发功能,是单键长按的一种变化。
基本长按,是按键按下超过1秒,一旦超过1秒则返回一个“长按事件”,然后必须等待本次按键释放。如果按键按下3秒才释放,返回的也只是一次“长按事件”。
连_发是建立在长按的基础上,当按键按下超过1秒,一旦超过1秒则返回一个“连_发事件”,如果此时按键仍然按下,则每隔300ms返回一个“连_发事件”。因此如果按键也是按下3秒才释放,则在1秒后返回了大约7个“连_发事件”,每次间隔300ms。
应用事例1:PC的按键,在编辑输入状态,按下A健不放手,稍微等待后便输入一串“A”
应用事例2:手机键盘,短信输入,英文字符输入方式,按下2键不放,延时一段时间后,输入字母A-B-C-2,不停的自动转换,放开按键,则最后一个字母为确认的输入符号。
应用事例3:时钟时、分、秒的设置,比如设置在秒时,单击按键,秒的个位加1,按下按键不放,超过1秒后,每300ms秒的十位加1(参考我编写教材的例9.2)
以下是书里面的参考代码:(这个只用一个最底层,完成单击和连_发的判断)
下面是基于状态机方式编写的带“连_发”功能按键接口函数read_key_n(),每10ms调用一次。
#define key_input& & & & PIND.7& & & & // 按键输入口
#define key_state_0& & & & 0
#define key_state_1& & & & 1
#define key_state_2& & & & 2
#define key_state_3& & & & 3
unsigned char read_key_n(void)
& & static unsigned char key_state = 0, key_time = 0;
& & unsigned char key_press, key_return = 0;
& & key_press = key_& && && && && && && && && && && && &&&// 读按键I/O电平
& & switch (key_state)
& && &&&case key_state_0:& && && && && && && && && && && && && &// 按键初始态
& && && && &if (!key_press) key_state = key_state_1;& && && && &// 键被按下,状态转换到键确认态
& && && && &
& && &&&case key_state_1:& && && && && && && && && && && && && &// 按键确认态
& && && && &if (!key_press)
& && && && &{
& && && && && & key_state = key_state_2;& && && && && && && && &// 按键仍按下,状态转换到计时1
& && && && && & key_time = 0;& && && && && && && && && && && &&&// 清另按键时间计数器
& && && && &}
& && && && &else key_state = key_state_0;& && && && && && && &&&// 按键已抬起,转换到按键初始态(此处完成按键消抖,按下和释放其实都在这里完成的)
& && && && &
& && &&&case key_state_2:
& && && && &if (key_press)
& && && && &{
& && && && && & key_state = key_state_0;& && && && && && && && &// 按键已释放,转换到按键初始态
& && && && && & key_return = 1;& && && && && && && && && && && &// 输出“单击”
& && && && &}
& && && && &else if (++key_time &= 100)& && && && && && && && & // 按键时间计数
& && && && &{
& && && && && & key_state = key_state_3;& && && && && && && && &// 按下时间&1s,状态转换到计时2
& && && && && & key_time = 0;& && && && && && && && && && && &&&// 清按键计数器
& && && && && & key_return = 2;& && && && && && && && && && && &// 输出第一次“连_发事件”
& && && && &}
& && && && &
& && &&&case key_state_3:
& && && && &if (key_press)
& && && && && & key_state = key_state_0;& && && && && && && && &//按键已释放,转换到按键初始态
& && && && &else
& && && && &{
& && && && && & if (++key_time &= 50)& && && && && && && && && &// 按键时间计数
& && && && && & {
& && && && && && &&&key_time = 0;& && && && && && && && && && & // 按下时间&0.5s,清按键计数器
& && && && && && &&&key_return = 2;& && && && && && && && && &&&// 输出又一次“连_发事件”
& && && && && &&&}
& && && && &}
& && && && &
& & }& & & &
& & return key_
=====================================================
可以发现,与LZ位的代码变化不大,增加了一个状态,适当调整以下就行了,变量都不多一个。
你变我也变,但是我的基本结构不变,因此状态机+按键的扫描这样的结构,可以做到“以不变应万变”。
回头看了下48楼你的状态图,确实搞复杂了,正规军的干活,小小的单片机还不够你布阵的。
马老师的这个题目非常好,把状态机用活了,可以活的很富态(堆大量的程序),也可以活的很精炼。
同学们一定要做好这道题,一举两得啊(状态机+多功能按键)。
我编写的教材,尽管里面的代码是在AVR上跑的,但里面大量的分析方法、设计理念、编程思路是其它众多介绍51、AVR、甚至是32位单片机的书所没有的,处理和思考的角度都是非常全面的,如果认真学习和体会,收获会大大超过看其它的参考书。
& & 学习单片机没有任何的“捷径”,但在打基础的阶段,入门学习的开始,使用一本好书,可以让你在整个技术人生和发展生涯中少走很多的弯路,有着正确和坚实的基础,从事实际的设计应用和向高层次发展。
& & 由于我编写教材中,决大部分代码是C的代码,因此,不管你使用什么型号的单片机,哪怕你使用STM32,都可以参考我编写的教材。其实代码并不十分重要,关键是理解和掌握思想方法,和分析与解决问题的能力。
& &&&我第2版教材中的应用,涉及到了SD卡、FAT文件系统、WAV文件结构、数字音频回放,这些都能在8位AVR上实现,而且与在32位系统上实现的方法是一样的。
回【145楼】 machao
“应用事例1:PC的按键,在编辑输入状态,按下A健不放手,稍微等待后便输入一串“A” ”
这个至少在PS2键盘协议里面是没有区分长按和连_发的,因为你只要按下键发的都是按键的通码,只不过第一次发按键通码是在你按下按键以后,第二次发出就是所谓的长按,第三次之后才是所谓的连_发,但不管是哪个状态发出都只有一个,那就是按键的通码,而且长按的时间间隔和连_发的时间间隔其实是下载到PC机键盘中执行的,并不是PC机本身的操作系统控制的。
【144楼】 zhanan
头一回听说状态机还有隐藏状态,如果这样的话大家都不用画状态图了,直接就说我这个状态图都是隐藏的好了。无键状态在这个状态机中是个非常重要的状态,甚至比单击,连击这种状态还要重要,没有它真不知道后续按键怎么处理了。
回复【148楼】igoal
回【145楼】 machao&&
这个至少在ps2键盘协议里面是没有区分长按和连_发的,因为你只要按下键发的都是按键的通码,只不过第一次发按键通码是在你按下按键以后,第二次发出就是所谓的长按,第三次之后才是所谓的连_发,但不管是哪个状态发出都只有一个,那就是按键的通码,而且长按的时间间隔和连_发的时间间隔其实是下载到pc机键盘中执行的,并不是pc机本身的操作系统控制的。
-----------------------------------------------------------------------
1、“pc键盘芯片”处理按键是否要按马老师的程序思想做?ps2协议已经是我们这个程序的输出级了。每个按键松手还要发个“断码”呢
2、ps2协议只是现实世界万千按键应用的1种,你不能只按照这一种思路思考啊。
对于俺这个初学者,这个帖子太及时了。
先mark,谢谢
回复【147楼】machao
&&我第2版教材中的应用,涉及到了sd卡、fat文件系统、wav文件结构、数字音频回放,
-----------------------------------------------------------------------
您第2版教材全称是什么?谢谢
回复【153楼】packer
回复【147楼】machao&&
&&我第2版教材中的应用,涉及到了sd卡、fat文件系统、wav文件结构、数字音频回放,
-----------------------------------------------------------------------
您第2版教材全称是什么?谢谢
-----------------------------------------------------------------------
马老师专栏的置顶帖里就有写了
《AVR单片机嵌入式系统原理与应用实践》(第2版)新书正式发行了。书号为:978-7-,北京航空航天大学出版
mark,支持马老师
感谢马老师,我等茅塞顿开,凡是看透的帖子MARK!没看透的收藏夹伺候!
mARK,感谢马老师。以前只会用中断实现过此功能,现在茅塞顿开啦。。
双击一下子把按键复杂了一点,大家应该积极探讨此贴才更有意义。
按照马老师的程序,如果双击的时候,第二击在过了双击时限才松手,将会得到什么结果呢?
(原文件名:短击双击.jpg)
这个问题分两步考虑
首先,要定义好这种情况应该按什么处理。这里就有用户体验感,不同的人会有不同要求。可以双击,可以长按,甚至无效。
第二步,才是如何实现。其实如能完全理解马老师的程序,这步是极其easy的。
我个人认为,这是一次双击。
判断长按和短按比较实际,三种状态的没意义,容易产生误操作。设计要跟现实使用相结合。
回复【164楼】packer
-----------------------------------------------------------------------
现在想深入探讨一下马老师的程序,引出一些有意义的东西。马老师的程序在于抛玉引砖,希望引来更多的砖头,好解决更多的实际问题。
如果第一次短击后,按下按键等到发生短击反应后再松手(在长按之前松手,分别将双击时限和长按时限调到1S和2S便于观察),将会发生又一次短击,这样的结果可能是不需要的吧。
另外,在这个题目里,双击里面判断短击,会造成延迟,可能还会比较严重。有办法改进吗?
【144楼】 zhanan&&
头一回听说状态机还有隐藏状态,如果这样的话大家都不用画状态图了,直接就说我这个状态图都是隐藏的好了。无键状态在这个状态机中是个非常重要的状态,甚至比单击,连击这种状态还要重要,没有它真不知道后续按键怎么处理了。
-----------------------------------------------------------------------
我所说隐含的,是指功能隐含,你总不能把无键也作为一个功能吧。但是无键状态是必须的,每次按键判断都是从无键状态开始的。
回复【167楼】zhanan
按下按键等到发生短击反应后再松手
-----------------------------------------------------------------------
如不是笔误就是逻辑错误。短击是松手后才能得出的结论
回复【168楼】packer
-----------------------------------------------------------------------
可能是我描述的不清楚,因为把按键状态这样细分大概是史无前例的,我也是在探讨中,用词主要是用于区分不同的按键状态。
我所说的是马老师的程序:一次短击、时限内两次短击、长按都是没有问题的,符合题目要求。
& && && && &现在的问题:一次短击,然后再按下不放,从上次松开到双击时限,这时会发一个短击码。过了这个时限(当然短于长按)松手,等到双击时限的时候又会发一个短击码。就是说,这种按法,会发出两个短击码。
对还是不对?有必要讨论一下。
双击码肯定是要在时限内实现,这种犹豫的双击按法最好产生一次短击码,或者产生一个无键码。
回复【169楼】zhanan
-----------------------------------------------------------------------
太困了,脑子不太清楚,大概说说我的看法。
第一次按键,因不知是短击还是长按,所以要等松手。所以第一次是“短击”。在双击时限内,第二次按下时,直接判定为双击,输出双击码,并等松手回无键状态。
貌似现在程序就这么做。
如果,第二次的按键也要判时间长度,看是否是长按,那就要事先规定好各种情况,分别如何处理。然后才能继续详细讨论下去。
回复【163楼】zhanan
双击一下子把按键复杂了一点,大家应该积极探讨此贴才更有意义。
按照马老师的程序,如果双击的时候,第二击在过了双击时限才松手,将会得到什么结果呢?
(原文件名:短击双击.jpg)
-----------------------------------------------------------------------
此时我的代码返回的是两个单击事件。
仔细看底层代码,它返回的是“短按”和“长按”,区别在于
1:短按按下时间&1S,长按的按下时间&1s
2:短按返回是在按键释放,长按的返回在按下时间达到1S时就返回了(不用等释放)
而中间层是根据2次返回的“短按”间隔判断是否有双击的,由于底层的短按都是在按键释放才返回,因此这个双击间隔0.5s实际是两次按键释放的间隔&0.5s为一次“双击”。
你的这中按法,在第一次短按释放后,尽管马上又按下了按键,但在0.5s内没有释放,不返回第二短击,所以第1次为单击,后面的那个“比较长的”短按,也是作为1次单击的。
====================================================================
看看与定义有矛盾吗?
1。两次都是短按,因为按下时间&1s。程序不会出现长按事件
2。那么这两次的短按,只有2种可能:1次双击或2次单击。
在看我在LZ位的“双击”定义:
“双击事件:2次短按操作间隔时间&0.5s,则2次短按操作为1次双击事件,且2次短按都取消 ”
这个定义是面向用户的,表述也是明确的“2次短按操作间隔时间&0.5s”。对于用户“短按操作”是按一个键的整个过程(释放掉)。因此zhanan的按法,第2个操作没有在0.5秒内完成,所以不能作为双击操作。
实际使用中,这样的按键操作属于用户处在犹豫状态或思考问题状态,返回2次单击是合理的,也符合定义。
======================================================
由于是多功能键,要判断长按,那么短按只能在释放时才能被确认。如果没有长按功能的定义,这个延误可以没有。
由于要判断双击,那么第1次单击的确认需要在短按发生后延时0.5s。我的定义和代码为1个双击替代2个单击。你也可以将两次间隔时间短的短按操作定义成1次单击和1次双击,那么这个延误就可以取消。
以上通过调整代码都是可以做到的。
===========================================================
所以,我指出多功能按键的设计,首先在于你是否能明确的理清楚各个功能之间的关系,然后才是程序的设计。
“我指出多功能按键的设计,首先在于你是否能明确的理清楚各个功能之间的关系,然后才是程序的设计。”马老师所言极是,所以按键处理没有通用程序可以直接抄来就用,特别是少键多功能,都是从各种按法中选择几种和功能挂钩。
比如双击功能,packer却是这样定义的:
第一次按键,因不知是短击还是长按,所以要等松手。所以第一次是“短击”。在双击时限内,第二次按下时,直接判定为双击,输出双击码,并等松手回无键状态。
分析:第一次单击,先扣下,如果是长按,发长按码,然后等放开。
& && && && && && && && &&&如果在双击时限内又一次单击,发双击码,然后等放开。
& && && && && && && && &&&如果在双击时限内没有再一次单击,时限到时,发单击码。
& && &其他情况均为无键。
& && &单击和双击限制在双击时限内。
不多说了,抛砖。
/***************/
uchar key_driver(void)& &// 读键盘
&&static uchar key_state=0, key_time=0;&&// 状态、按键计时
&&uchar key_press,key_&&// 按键值、返回事件
&&if(key_input) key_press=0; else key_press=1; // 读引脚:松开0,按下为1。
&&key_return=0;& & // 返回事件清0
&&switch (key_state)
& && &case 0:& & // 按键初始态&&
& && &&&if (key_press==1) key_state=1;& && &// 键被按下,状态转换到按键消抖和确认状态&&
& && &&&&&
& && &case 1:& & // 按键消抖与确认态&&
& && &&&if (key_press==1)&&
& && &&&{&&
& && && && & key_time =0;& &//& &
& && && && & key_state=2;& &// 按键仍然处于按下,消抖完成,状态转换到按下键时间的计时状态
& && && && & key_return=11; // 【返回单击事件11】&&
& && &&&}&&
& && &&&else&&
& && && && & key_state=0;& &// 按键已抬起,转换到按键初始态。此处完成和实现软件消抖,其实按键的按下和释放都在此消抖的。&&
& && &&&&&
& && &case 2:
& && &&&if(key_press!=1)& & // 按键释放
& && &&&{&&
& && && && & key_return=1;&&// 返回按键释放事件
& && && && & key_state =0;&&// 转换到按键初始态&&
& && &&&}&&
& && &&&else if(++key_time &= 50)&&// 继续按下,计时加40ms(40ms为本函数循环执行间隔)&&
& && &&&{&&
& && && && & key_return=3;&&// 按下时间&2000ms,此按键为长按操作,返回长键事件&&
& && && && & key_state =3;&&// 转换到等待按键释放状态
& && &&&}&&
& && &&&&&
& && &case 3:& && && && && &// 等待按键释放&&
& && &&&if (key_press!=1) key_state =0; //按键已释放,转换到按键初始态&&
& && &&&&&
& & return key_&&
/*=============&&
中间层按键处理函数,调用低层函数一次,处理双击事件的判断,返回上层正确的无键、单键、双键、长键4个按键事件。&&
本函数由上层循环调用,间隔40ms&&
===============*/&&
unsigned char key_read(void)&&
& & static unsigned char key_m =0, key_time_1 = 0;&&
& & unsigned char key_return =0,key_&&
& & key_temp = key_driver();&&// 读键码
& & switch(key_m)&&
& && &&&case 0:&&
& && && && &if (key_temp ==11 )& & // 第1次单击
& && && && &{&&
& && && && && &&&key_time_1 = 0;& &// 初始化双击计时&&
& && && && && &&&key_m = 1;& && &&&// 转下一步
& && && && &}&&
& && && && &&&
& && &&&case 1:& && && && && && &&&// 第一次单击后的按键变化
& && && && &if(++key_time_1&12)& & // 双击时限内12x40=480mS
& && && && &{
& && && && &&&if (key_temp ==1)& & // 按键松开&&
& && && && &&&{&&
& && && && && &&&key_m=2;& && && & // 切换到双击判断
& && && && &&&}&&
& && && && &}
& && && && &else& && && && && && & // 双击时限外
& && && && &{
& && && && &&&if(key_temp==1) {key_m=0;}& && && && && & // 按键松开,回初始态
& && && && &&&if(key_temp==3) {key_return=3; key_m=0;}&&// 有长按,返回长键码,然后回初始态
& && && && &}
& && && && &
& && &&&case 2:& && && && && && &&&// 双击判断
& && && && &if(++key_time_1&12)& & // 时限内480mS
& && && && &{
& && && && &&&if(key_temp==11)& &&&// 再一次单击
& && && && &&&{
& && && && && &&&key_return=2;& &&&// 返回双击码
& && && && && &&&key_m=0;
& && && && &&&}
& && && && &}
& && && && &else& && && && && && & // 时限外
& && && && &{
& && && && &&&key_return=1;& && &&&// 无第二次单击,返回单击码
& && && && &&&key_m=0;
& && && && &}
& && && && &
& & return key_&&
/***************/
(程序改编自马老师的程序)
图示,反应要快些。
(原文件名:单击双击.jpg)
楼上中间的图,如果第2次按下的时间超过1秒才释放,算什么?1次双击还是1次单击+1次长按?
我觉得,这个帖子的目的已经达到,初学者如果能认真看马老师的程序,并融会贯通,就能掌握核心概念,以后灵活应用。
象马老师楼上问的,我觉得不能一概而论,要根据实际系统情况,选择最合适的处理方式。
我想到有这么几种
2、单击+长按
4、无效(这个好像不太合理)
还有一种,仅单击无长按,我觉得更不合理,就不列其中
但不论什么处理方式,只要定义好规则,我们都能应用本帖的概念,轻松实现。
回复【3楼】linghu2 令狐二中
-----------------------------------------------------------------------
正解,用一个定时器,什么都搞定了
楼上的真有意思,就用1个定时器裸奔,你能实现?
来来来,给我们演示演示。
回复【175楼】machao
楼上中间的图,如果第2次按下的时间超过1秒才释放,算什么?1次双击还是1次单击+1次长按?
-----------------------------------------------------------------------
按照packer的要求,双击是判断按键的前沿,第二击只要按下就算双击,作出双击反应,过了时限(即使过了长按时限)松开,算无键。
回复【176楼】packer
我觉得,这个帖子的目的已经达到,初学者如果能认真看马老师的程序,并融会贯通,就能掌握核心概念,以后灵活应用。
象马老师楼上问的,我觉得不能一概而论,要根据实际系统情况,选择最合适的处理方式。
我想到有这么几种
2、单击+长按
4、无效(这个好像不太合理)
还有一种,仅单击无长按,我觉得更不合理,就不列其中
但不论什么处理方式,只要定义好规则,我们都能应用本帖的概念,轻松实现。
-----------------------------------------------------------------------
我觉得该帖才刚入正题,帖子前部分妄想和windows及手机带os的系统去比较,这样比下去只有无解。我想把探讨引入到按键状态图和程序上,针对具体功能,实现程序,对初学者才真正有帮助,我想这也是马老师特开此帖并置顶的初衷。
当然我一个人的能力是有限的,需要众人支持,特别的初学者应该踊跃参与,现在条件对初学者很有利:
1. 马老师目前将此帖作为一个重点,半夜三更还回帖,多令人感动。
2. 此程序不挑单片机,资源要求简单之极,状态变化又多,多好的编程实例。现在还只是单键多功能,多键多功能呢?如何优化?
3. 这个也是学习状态机的好帖,如何从各种状态中找到满足功能需求的状态,然后用程序来实现。
172楼的程序应该是比较实用的,快速按两下肯定是双击,只按一下松手&0.5S算单击,一犹豫过了0.5S算无效(无键),一直按着到长按时限算长键(为方便实验,把长按改为2秒)。双击时限从按键前沿开始算,感觉反应比较快。
和马老师的原程序比,把按键的前沿利用起来了,按键一旦确定按下了,底层程序先发一个11。( key_return=11; // 【返回单击事件11】 )
怎么没有人拍砖?我拍几块金砖大家看看成色如何?
在135楼,我说过:状态表的形式可不一定仅仅是状态编号,计时器的值也表明一定的状态!在按键的底层和中层程序都用到了计时器,可以利用这个特点对程序优化一下:
【172楼】的底层程序优化一下:
uchar key_driver(void)& &// 读键盘
&&static uchar key_last, key_&&// 上次键值、按键计时
&&uchar key_press,key_return=0;&&// 按键值、返回码
&&if(key_input) key_press=0; else key_press=1; // 读引脚:松开0,按下为1。
&&if(key_press!=key_last) {key_last=key_ key_time=0;}&&// 新键值
&&if(key_time==1) key_return=(key_press==1)?11:1;&&// 按下及松开
&&if(key_time==50 && key_press==1) key_return=3;& &// 长按
//&&if(key_time==55 && key_press==1) key_return=4;& &// 连按
&&if(++key_time&60) key_time=55;&&// 最长限制(或连按间隔)
&&return key_&&
看起来还像是用状态机吗?只用了一句就把连按加上了,按键前后都带消抖的。
在占一楼加分。
把【172】楼的中层程序也优化一下:
/*=============&&
中间层按键处理函数,调用低层函数一次,处理双击事件的判断,返回上层正确的无键、单键、双键、长键4个按键事件。&&
本函数由上层循环调用,间隔40ms&&
===============*/&&
unsigned char key_read(void)&&
& & static unsigned char key_last =0, key_time_1 = 0;&&
& & unsigned char key_return =0,key_&&
& & key_temp = key_driver();&&// 读键码
& & if(key_time_1==0)& && && &// 初始态
& && &if(key_temp==11) key_time_1++;&&// 启动双击计时
& & else if(++key_time_1&12) // 双击时限内
& && &if(key_temp==11) {key_temp=key_time_1=0; key_return=2;}&&// 时限内又按下,双击
& & else& && && && && && && &// 双击时限到
& && &if(key_last==1) key_return=1;&&// 单击
& && &key_time_1=0;
& & if(key_temp==3&&key_last==11) key_return=3;& &// 长按,直接返回
& & if(key_temp) key_last=key_ // 保存本次键码
& & return key_&&
斗胆把马老师的程序也优化一下吧!
马老师的底层程序优化:
uchar key_driver(void)& &// 读键盘
&&static uchar key_last=0, key_time=2;&&// 上次键值、按键计时
&&uchar key_press,key_return=0;&&// 按键值、返回码
& &if(key_input) key_press=0; else key_press=1; // 读引脚:松开0,按下为1。
&&if(key_press!=key_last) {key_last=key_ key_time=0;}&&// 新键值
&&if(key_time==1) key_return=(key_press==1)?11:1;&&// 按下及松开
&&if(key_time==50 && key_press==1) key_return=3;& &// 长按
//&&if(key_time==55 && key_press==1) key_return=4;& &// 连按
&&if(++key_time&60) key_time=55;&&// 最长限制(或连按间隔)
&&return key_&&
改了一个变量名:key_state改为key_last,为了更贴切些。
马老师的中层程序优化:
/*=============&&
中间层按键处理函数,调用低层函数一次,处理双击事件的判断,返回上层正确的无键、单键、双键、长键4个按键事件。&&
本函数由上层循环调用,间隔40ms&&
===============*/&&
unsigned char key_read(void)&&// 单击双击都是后沿起作用
& & static unsigned char key_last =0, key_time_1 = 0;& &
& & unsigned char key_return =0,key_& &
& & key_temp = key_driver();&&// 读键码
& & if(key_time_1==0)& && && &// 初始态
& && &if(key_temp==1&&key_last==11) key_time_1++;& & // 启动双击计时
& & else if(++key_time_1&12) // 双击时限内
& && &if(key_temp==1) {key_return=2; key_time_1=0;} // 时限内松开,双击
& & else& && && && && && && &// 双击时限到
& && &if(key_last==1) key_return=1;&&// 单击
& && &key_last=key_time_1=0;
& & if(key_temp==3&&key_last==11) key_return=3;& &// 长按,直接返回
& & if(key_temp) key_last=key_ // 保存本次键码
& & return key_& &
也改了一个变量名:key_m改为key_last,为了更贴切些。并且第二击,如果过了双击时限才松手,算无效。长按必须一直按着直到长键时刻,中间不能松开。
【181楼】和【183楼】都是按键底层程序,竟然是一样的了,通用了!用不到的功能把对应的那句删掉即可。多键也能在这个基础上很容易实现。
终于60分及格了。
马老师的双击的第二击改为用前沿,这样双击反应能快些。
unsigned char key_read(void)&&// 双击的第二击前沿起作用
& & static unsigned char key_last =0, key_time_1 = 0;&&
& & unsigned char key_return =0,key_&&
& & key_temp = key_driver();&&// 读键码
& & if(key_time_1==0)& && && &// 初始态
& && &if(key_temp==1&&key_last==11) key_time_1++;& & // 启动双击计时
& & else if(++key_time_1&12) // 双击时限内
& && &if(key_temp==11) {key_return=2; key_temp=key_time_1=0;} // 时限内又按下,双击
& & else& && && && && && && &// 双击时限到
& && &key_return=1;& && && & // 单击
& && &key_time_1=0;
& & if(key_temp==3&&key_last==11) key_return=3;& &// 长按,直接返回
& & if(key_temp) key_last=key_ // 保存本次键码
& & return key_&&
多谢,mark!
单击 + 双击 + 长按
如何实现连_发
这个不错。 按键功能。 双击,单击,长按。
回复【1楼】yuzr
-----------------------------------------------------------------------
谢谢马老师,认真学习!
mark 双击,单击,长按
mark!!!以后看!!!!谢谢楼主分享!!!!
马克了再细看
阿莫电子论坛, 原"中国电子开发网"

我要回帖

更多关于 个人简历编辑 的文章

 

随机推荐