用户名密码
自动登录登录
找回密码 注册
首页全部贴汇总请输入搜索内容
技术贴汇总非技术汇总帮助无图快速版搜索
搜索
阿莫电子邮购
热搜:雕刻机阿莫淘金春风电源
快捷导航
论坛首页开源已完成马潮AVR 题目:多功能按键设计。利用一个I/O口,接一个按键,实 ...
返回列表
1
2
3
4
5
6
7
8
1
/ 8 页
下一页
查看: 11538|回复: 292
题目:多功能按键设计。利用一个I/O口,接一个按键,实现3功能操作:单击 + 双击 + 长按。 [复制链接]
发表于 2011-8-23 18:12:42 |只看该作者 |倒序浏览
1楼
电梯直达
machao
oB
20709568主题好友
积分
版主
莫元9562
发消息
BS
阿
莫
题目:多功能按键设计。利用一个I/O口,接一个按键,实现3功能操作:单击 + 双击 + 长按。
============================================================================ 用户基本操作定义:
1。短按操作:按键按下,按下时间1s,属于一次长按操作
在正常0.5s 内无按键操作为启始按键扫描条件下,扫描按键将产生以下3种按键事件: 1。长按事件:任何1次出现的长按操作都属于长按事件 2。单击事件:1次短按操作后,间隔0.5内没有短按操作
3。双击事件:2次短按操作间隔时间
1。短按操作和长按操作间隔
对按键操作者的建议:
由于按键的多功能性质,建议操作者每次在单击/长按/双击按键事件发生后,隔0.5s 后再进行下一次的按键操作。因为在特别操作情况下,程序是保证按定义进行判断和处理的,主要是怕操作者自己记不清楚导致操作失误。
对软件设计者的要求:
1。应该全面进行分析,给出严格定义和判断条件,如上所示。如果自己都不清楚,你的设计出的系统就不稳定,不可靠。 2。在1的基础上,编写出符合要求的程序,并进行全面测试。
/*=============
低层按键(I/0)扫描函数,即低层按键设备驱动,只返回无键、短按和长按。具体双击不在此处判断。参考本人教材的例9-1,稍微有变化。教材中为连_发。
===============*/
#define key_input PIND.7 // 按键输入口 #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
unsigned char key_driver(void) {
static unsigned char key_state = key_state_0, key_time = 0; unsigned char key_press, key_return = N_key; key_press = key_input; // 读按键I/O电平
switch (key_state) {
case key_state_0: // 按键初始态
if (!key_press) key_state = key_state_1; // 键被按下,状态转换到按键消抖和确认状态 break;
case key_state_1: // 按键消抖与确认态 if (!key_press) {
key_time = 0; //
key_state = key_state_2; // 按键仍然处于按下,消抖完成,状态转换到按下键时间的计时状态,但返回的还是无键事件 } else
key_state = key_state_0; // 按键已抬起,转换到按键初始态。此处完成和实现软件消抖,其实按键的按下和释放都在此消抖的。 break;
case key_state_2: if(key_press) {
key_return = S_key; // 此时按键释放,说明是产生一次短操作,回送S_key key_state = key_state_0; // 转换到按键初始态 }
else if (++key_time >= 100) // 继续按下,计时加10ms (10ms 为本函数循环执行间隔) {
key_return = L_key; // 按下时间>1000ms,此按键为长按操作,返回长键事件 key_state = key_state_3; // 转换到等待按键释放状态 }
break;
case key_state_3: // 等待按键释放状态,此状态只返回无按键事件 if (key_press) key_state = key_state_0; //按键已释放,转换到按键初始态 break; }
return key_return; }
/*=============
中间层按键处理函数,调用低层函数一次,处理双击事件的判断,返回上层正确的无键、单键、双键、长键4个按键事件。 本函数由上层循环调用,间隔10ms ===============*/
unsigned char key_read(void) {
static unsigned char key_m = key_state_0, key_time_1 = 0; unsigned char key_return = N_key,key_temp;
key_temp = key_driver();
switch(key_m) {
case key_state_0:
if (key_temp == S_key ) {
key_time_1 = 0; // 第1次单击,不返回,到下个状态判断后面是否出现双击 key_m = key_state_1; } else
key_return = key_temp; // 对于无键、长键,返回原事件 break;
case key_state_1:
if (key_temp == S_key) // 又一次单击(间隔肯定
key_return = D_key; // 返回双击键事件,回初始状态 key_m = key_state_0; }
else
{ // 这里500ms 内肯定读到的都是无键事件,因为长键>1000ms,在1s 前低层返回的都是无键 if(++key_time_1 >= 50)
{
key_return = S_key; // 500ms内没有再次出现单键事件,返回上一次的单键事件 key_m = key_state_0; // 返回初始状态 } }
break; }
return key_return; }
下面,根据程序分析按键事件的反映时间: 1。对于长键,按下超过1s 马上响应,反映最快
2。对于双键,第2次按键释放后马上得到反映。
3。对于单键,释放后延时拖后500ms 才能响应,反映最慢。这个与需要判断后面是否有双击操作有关,只能这样。实际应用中,可以调整两次单击间隔时间定义,比如为300ms ,这样单击的响应回快一点,单按键操作人员需要加快按键的操作过程。如果产品是针对老年人的,这个时间
yuzr
不易太短,因为年纪大的人,反映和动作都比较慢。
当然,上面两段可以合在一起。我这样做的目的,是为了可以方便的扩展为N 击(当然,需要做修改)。可是最底层的就是最基本的操作处理短按和长按,不用改动的。至于双击,还是N 击,在中间层处理。这就是程序设计中分层结构的优点。 测试代码环境如下:
interrupt [TIM0_COMP] void timer0_comp_isr(void) // 定时器10ms 中断服务 {
time_10ms_ok = 1; }
main(viod) { ......... while {
if (time_10ms_ok) //每10ms 执行一次, {
time_10ms_ok =0;
key = key_read(); //《====== 10ms一次调用按键中间层函数,根据返回键值,点亮不同的LED 灯,全面测试按键操作是否正常
if (key == L_key)
........//点亮A_LED,关闭B_LED和C_LED else if(key == D_key)
........//点亮B_LED,关闭A_LED和C_LED else if(key == S_key)
........//点亮C_LED,关闭A_LED和B_LED } } }
=================================================
通过以上这个看似简单的按键,看在应用中如何变化,以及如何在实际产品中全面、可靠的进行设计。
=======================================================================================================后续:
这个是一个网友要求我做的东西,他买了我编写的教材,学习了里面的状态机按键设计,但还是不能灵活的使用。我提出让一些有兴趣的朋友做一下,大家讨论,(见http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=4971785&bbs_page_no=1&bbs_id=1003,28楼),但是很少人给出满意的回答。甚至是这样的回答:“晕,参加电设的也有很多强人,虽然不一定是精英,但还是很有实力的,这种题目很多人都很早就会做了,没必要当作电设的训练题。(见该贴30楼的回答)”。这个如同我去年挑战一个北大高才生一样,真本事没有,就是嘴硬。
既然别人不感“兴趣”,我编写代码,实现这个简单的多功能按键。这也是对这位购买我编写书的朋友的一种答谢吧。 写完后,还想扩展一点,发点“偏见”如下:
相比国际上的一些品牌产品,国内的很多东西都做不精。其中系统分析和软件设计占有重要的因素。其实不是不想做的好,而是根本没有能力做好!
如上这样一个简单的多功能按键,都分析不透,设计不出好的代码,就不要谈上天下海的吧。D 车追尾就是发生了特殊情况,设计中根本没有考虑周全,加上工作人员的不负责,产生如此大的灾难。
最近频繁出现的塌桥、电梯事故、火车出事,都是上天对现在浮躁社会的报应。我们都抱怨别人不负责,浮躁,那么你自己呢?
别人,别的行业我没有资格讲不好,但是对于正在学习的本专业大学生,尤其是要参加全国大学生电子设计大赛的学生,你做这个题目能拿多少分?评估一下有多少能力和水平?
实际上,现在的全国大学生电子设计大赛也变成是一个浮躁的产物,学校和学生都指望它能贴金,对于真正培养和锻炼人的目的和作用,实际上只是挂在前面遮羞布了。
本主题由 machao 于 2012-4-3 12:18 解除置顶
收藏54回复
举报 发表于 2011-8-23 18:28:38 |只看该作者
2楼
yuzr 发表于 2011-8-23 18:28:38 |只看该作者401092主题好友
积分
金牌会员
莫元
1088
发消息
surf_131
3201211主题好友
积分
金牌会员
莫元1105
发消息
linghu2
2702992主题好友积分
金牌会员令狐二中
莫元2920
发消息
ruizhixing
mark
回复
举报 发表于 2011-8-23 18:46:39 |只看该作者3楼
很有意义的帖子。
我这几天在PIC 平台上也考虑过同样的东西,但是今天放弃了三种不同键识别的办法,改用一长一短两个键实现需要的功能。是在定时中断中设置几个变量来识别长短键。这样,短键可以在抬键后一个中断周期内快速响应,长键则在按下后3秒左右才开始响应,并能用查询法等待上次长键结束。
如果允许的双击间隔是500ms ,则判断单点击要滞后500ms 以上,太迟钝了。
回复
举报 发表于 2011-8-23 19:03:14 |只看该作者4楼
如果连这么简单的东东都写不出来, 参加电设就是浮云
回复
举报 发表于 2011-8-23 19:08:43 |只看该作者
5楼
“实际上,现在的全国大学生电子设计大赛也变成是一个浮躁的产物,学校和学生都指望它能贴金,对于真正培养和锻炼人的目的和作用,实际上只是挂在前面遮羞布了。 ”
/***********************************************************************************************************/
最近看了一个帖子,说电设与高考的对比.... 百度上搜查“电子设计大赛 高考”。看来我得好好戒除自己的浮躁心态了...
11主题注册会员
0好友94积分
莫元
发消息
94
回复
ifree64
发表于 2011-8-23 19:19:45 |只看该作者
举报6楼
5501501主题好友
积分
金牌会员
莫元1501
发消息
machao
20709568主题好友
积分
版主
莫元9562
发消息
machao
20709568主题好友
积分
版主
莫元
9562
回复【2楼】surf_131 很有意义的帖子。
我这几天在pic 平台上也考虑过同样的东西,但是今天放弃了三种不同键识别的办法,改用一长一短两个键实现需要的功能。是在定时中断中设置几个变量来识别长短键。这样,短键可以在抬键后一个中断周期内快速响应,长键则在按下后3秒左右才开始响应,并能用查询法等待上次长键结束。
如果允许的双击间隔是500ms ,则判断单点击要滞后500ms 以上,太迟钝了。-----------------------------------------------------------------------在windows 平台上,鼠标双击事件的顺序大致为键按下、键抬起、双击键按下;这样不会出现单击滞后500ms 的问题了。
回复
举报 发表于 2011-8-23 19:44:02 |只看该作者
7楼
回复【2楼】surf_131 很有意义的帖子。
我这几天在pic 平台上也考虑过同样的东西,但是今天放弃了三种不同键识别的办法,改用一长一短两个键实现需要的功能。是在定时中断中设置几个变量来识别长短键。这样,短键可以在抬键后一个中断周期内快速响应,长键则在按下后3秒左右才开始响应,并能用查询法等待上次长键结束。
如果允许的双击间隔是500ms ,则判断单点击要滞后500ms 以上,太迟钝了。-----------------------------------------------------------------------手机有吧。打开进入短信编辑状态,设置输入方式为英文,然后操作一个键单击、双击、长按,看屏幕输入有何变化。但是你在打电话,输入电话号码的时候,此时只响应单击,和长按了。单击就是在释放后响应的。双击此时是两次单击。在不同的工作状态,可以对不同按键操作做不同的处理。掌握了这些,就能设计出好的系统。
回复
举报 发表于 2011-8-23 20:18:49 |只看该作者8楼
回复【5楼】ifree64
-----------------------------------------------------------------------
在windows 平台上,鼠标双击事件的顺序大致为键按下、键抬起、双击键按下;这样不会出现单击滞后500ms 的问题了。 -----------------------------------------------------------------------你分析的不对。
在windows 平台上,鼠标双击事件为左键快速按两下,之间还是有时间间隔定义的。单其定义不同:
我们以双击打开文件夹中一个WORD 文件为例:
将鼠标运动指在这个文件上,然后单击,表示选中该文件,如果快速双击,则表示选中该文件,并打开。你可以测试一下,如果将鼠标运动指在这个文件上,然后单击,过长点时间再次单击,是不会打开文件的。
所以,此时windows 平台的定义为:
发消息
所以,此时windows 平台的定义为:
第1次单击为选中该文件,如果第2次单击的时间与前面选择文件的单击间隔小于一定的时间,就自动打开该文件。因此,它的第一次单击不需要等待,可以马上动作。只是判断第2次单击与此次的间隔,如果小,属于双击,自动打开文件,如果长,则仍旧表示选择该文件。 而在嵌入式系统中,有时没有屏幕光标的辅助,这样处理反而不方便。
在这个题目开始,我已经定义的操作过程。如果按windows 平台上的鼠标双击事件,也是容易做到的,但此时“双击”的定义就不同了。
另外,windows 平台上的鼠标很少处理长按。如果有长按,那么单击就不可能马上被响应,必须等待到释放,看按下的时间才能判断是单击或长按。
先仔细体会一下,操作操作,再提出你的看法。我的贴子,不是一般的肤浅东西。
应一句老话,没有金刚钻,就不会揽这些瓷器活。否则我也不敢吹嘘我编写的教材。出版此类教材的教授多了,有几个真正设计产品,亲自编写代码的?都是理论加肤浅和不实用的代码。
不好意思,晚上灌了的啤酒,说酒话。不过,酒话往往是真话和实话。
回复
举报9楼
HQkiller1 发表于 2011-8-23 22:16:15 |只看该作者
004主题好友积分
游客莫元
4
发消息
HQkiller1
004主题好友
积分
游客莫元4
发消息
packer
20542主题好友
积分
高级会员
莫元542
发消息
HQkiller1
老师,阅读你的帖子和教材我获益匪浅,今天我在看你出版AVR 教材,对于你的教材中的第十五章:串行SPI 接口应用 中的例15_1的源程序存在一下疑问:
基于74HC164并利用SPI 口实现8路并口输出的扩展(原书P437页)以下给出我存在疑问的源程序的一部分:#difine SPIF 7....
while (!(SPSR&(1
//SPI初始化SPCR=0x50;SPSR=0x01;
您在书中while 语句后的注释为“等待SPI 完成”但是我觉得你的程序好像不能实现这个功能
首先你把SPIF 定义为7(0000_0111)让后与SPSR (0000_0001)位与,在while 循环中只循环了5次就跳出了while 循环,而要传送的是一个字节的数据(8位)所以我觉得你的程序在还没有将8位数据串行传输完就已经去执行下面的显示语句了,好像不能达到要求也有可能是我没看懂马老师精妙的程序,还望不吝赐教
回复
举报 发表于 2011-8-23 22:27:32 |只看该作者
10楼
马老师,在AVR 教材中第十五章:串行SPI 接口应用,例 15.2中您用采用完结A/D的方法实现数字万用表的功能,可是ATmega16只是8位的单片机,请问用没用什么办法用你的AVR 开发板实现十二位的A/D转换呢?
我用的是TI 的TLV2543芯片,是十二位的D/A芯片,用你讲的SPI 的办法好像不行,应为ISP 数据寄存器只有8位,无法存储12位转化结果
回复
举报 发表于 2011-8-23 22:39:42 |只看该作者11楼
受益匪浅。不大会画状态图,献丑了。
根据马老师程序画的状态图 (原文件名:machao.JPG)
回复
举报 发表于 2011-8-23 22:52:35 |只看该作者
12楼
呵呵,用马老师的AVR 实验板已经成功实现了以上按键要求
0主题游客莫元
0好友4积分
4
发消息
回复
roy2002
发表于 2011-8-23 23:02:09 |只看该作者举报13楼
290653主题好友积分
高级会员
莫元626
发消息
stefgq
300868主题好友积分
高级会员
莫元868
发消息
elecfun
5101660主题好友积分
金牌会员
莫元1671
发消息
果断MARK
回复
举报 发表于 2011-8-23 23:30:36 |只看该作者14楼
很好
回复
举报 发表于 2011-8-24 01:14:34 |只看该作者
15楼
刚在WIN7平台上试了下鼠标左键:
____-_----- 即短按+短间隔+长按,在长按还没有松开前系统已经认为是双击。____---_-__ 即长按+短间隔+短按,判定为两个(间隔较长的)单击。
这样看来,WIN7上判断鼠标左键按下,是有个超时处理机制。超过一定时间即认为按键已按下。
鼠标右键:
在某文件上右键长按,松开后才会显示文件右键相关菜单项。如果右键按下期间鼠标移动过,则会显示 到当前位置 相关菜单。如果你的浏览器支持右键动作,也可以试试(小心,别执行了关闭当前窗口的动作~~)。
然后进行另外几项测试:
1. 单击选中某个文件,然后在文件名处单击(即修改文件名),会等大概500ms 的样子,才进入修改主文件名状态。
2. 单击选中某个文件,然后在文件名处双击,可以看到,文件会被直接打开而不会进入文件名修改状态。
3. 就在你现在看到的文字位置处,单击,然后间隔稍长,再单击(些过程实质为双击,间隔稍长是为了更清楚的看到过程), 你会看到光标在第一次单击时就移过来了,第二次单击时就是双击选中的效果。
4. 打开记事本,鼠标移到“文件”菜单项上,然后双击。你会看到依然是单击的效果,显示相关下拉菜单。
5. 打开记事本,单击“文件”菜单项,显示相关下拉菜单;第二次单击“文件”菜单项,下拉菜单收回;第三次单击“文件”, 下拉菜单再次显示。
6. 打开记事本,单击“文件”菜单项,显示相关下拉菜单,然后双击菜单(如 文件),你会看到相关下拉菜单项会“刷新”一 下(是不是5中的收回再显示呢?)。
7. 打开IE8,如果隐藏了菜单栏按 Alt 键,以显示。双击“文件”,可以看到相关下拉菜单显示后又立即收回(是不是两个单击?)。8. 双击IE8工具栏上的“页面”按钮 或者 Chrome 右上角的设置按钮,可以看到相关下拉菜单显示后又立即收回。
综上7条,是不是可以看出,WIN7上不同的应用程序对单击、双击的操作不同?
回复
kenluo
发表于 2011-8-24 09:08:56 |只看该作者举报
16
楼
140338主题好友积分
游客莫元
338
发消息
kingsabbit
4301589主题好友积分
金牌会员
莫元1540
发消息
surf_131
3201211主题好友
积分
金牌会员
莫元1105
发消息
楼主, 按键方面处理的方法不错
回复
举报 发表于 2011-8-24 10:21:58 |只看该作者17楼
看过类似的做法, 但没真正写过
回复
举报 发表于 2011-8-24 10:59:54 |只看该作者18楼
长键则在按下后3秒左右才开始响应,----------------------------------------今天利用这个长键状态做了个延迟灯,一旦有键按下就点燃。发现延时不是3秒,而是2秒。这让那个延迟略显仓促。不过暂时不改了。当初是为了加快按键响应把定时器间隔减小了。特此说明。
回复举报
whhityang 发表于 2011-8-24 11:25:01 |只看该作者19楼
360417主题好友积分
中级会员
莫元
405
发消息
zjy9430
00326主题好友积分
中级会员
莫元
323
发消息
stoneee 150139主题好友积分
注册会员
莫元136
发消息
farmer
40238主题好友
积分
中级会员
莫元238
发消息
看那个帖子时想着随便写写就很好写出双击、长按的,只是脑子里过了下大概写法就过去了。现在再看马老师的写法,发现想法和实现出来还真是有点差距的,尤其是完美的实现。又一次见识到了马老师严谨细致的态度,受教了。
回复
举报 发表于 2011-8-24 11:32:43 |只看该作者20楼
参考一下
回复举报
发表于 2011-8-24 14:44:53 |只看该作者21楼
按键状态机,好用!
回复
举报 发表于 2011-8-24 16:39:53 |只看该作者22楼
按键状态机,好用!
回复
dongzhiqing
发表于 2011-8-24 16:42:35 |只看该作者举报
23
楼
420620主题好友
积分
高级会员
莫元620
发消息
HQkiller1004主题好友积分
游客莫元
4
发消息
kihell
80235主题好友积分
中级会员
莫元233
发消息
ifree64
5501501主题好友积分
金牌会员
顶一下。
回复举报
发表于 2011-8-24 16:56:02 |只看该作者24楼
不要灌水,有意义么
回复【22楼】dongzhiqing
-----------------------------------------------------------------------
回复
举报 发表于 2011-8-25 21:41:32 |只看该作者25楼
为什么 每次进入子函数都要把
key_state = 0呢
unsigned char key_driver(void) {
static unsigned char key_state = key_state_0, key_time = 0;
回复
举报 发表于 2011-8-25 21:57:04 |只看该作者26楼
回复【7楼】machao
回复【5楼】ifree64
-----------------------------------------------------------------------
在windows 平台上,鼠标双击事件的顺序大致为键按下、键抬起、双击键按下;这样不会出现单击滞后500ms 的问题了。 -----------------------------------------------------------------------你分析的不对。
在windows 平台上,鼠标双击事件为左键快速按两下,之间还是有时间间隔定义的。单其定义不同:我们以双击打开文件夹中一个word 文件为例:
将鼠标运动指在这个文件上,然后单击,表示选中该文件,如果快速双击,则表示选中该文件,并打开。你可以测试一下,如果将鼠标运动指在这个文件上,然后单击,过长点时间再次单击,是不会打开文件的。所以,此时wi......
-----------------------------------------------------------------------
莫元
发消息1501不知马老师是否熟悉Windows 平台上的程序开发,我的话是没有错误的,请看如下这句引自MSDN 的原话(http://msdn.microsoft.com/en-us/library/ms645606(v=vs.85).aspx)
Only windows that have the CS_DBLCLKS style can receive WM_LBUTTONDBLCLK messages, which the system generates whenever theuser presses, releases, and again presses the left mouse button within the system's double-click time limit. Double-clicking the left mousebutton actually generates a sequence of four messages: WM_LBUTTONDOWN, WM_LBUTTONUP, WM_LBUTTONDBLCLK, andWM_LBUTTONUP
这就是一个双击事件并不是只有一个WM_LBUTTONDBLCLK消息,而是按照先后顺序有4个消息;至于如何对这四个消息如何处理是应用程序自己的事。
如果只需要处理单击事件,响应WM_LBUTTONDOWN消息即可,要处理双击事件,就响应WM_LBUTTONDBLCLK,这样处理单击的事件的应用程序也不会
引入500ms 的延迟,处理双击的也可得到这个双击事件。至于两次单击之间是多长的时间,这只是一个系统的参数而已。
回复
packer 发表于 2011-8-25 22:41:01 |只看该作者举报27楼20542
主题好友积分
高级会员
莫元542
发消息
packer
20542
主题好友积分
高级会员
莫元542
发消息
cne53102
110297
主题好友积分
中级会员
莫元297
发消息
ifree64回复【24楼】kihell 红舞林檬浩为什么 每次进入子函数都要把 key_state = 0呢 unsigned char key_driver(void) { static unsigned char key_state = key_state_0, key_time = 0; -----------------------------------------------------------------------没用c 写过程序,只用汇编的人说说我的理解,望指正定义为static 类型,只在系统初始化赋此值注意下一句就没定义成static ,所以key_return = N_key每次调用都会被执行这也是我画状态图时很犹豫的地方,不知该如何表示回复举报 发表于 2011-8-25 23:04:32 |只看该作者28楼25楼的兄弟,你没理解马老师的意思当你第一次单击之后,神仙也不知道这是单击还是双击这时有2种处理方法1、等待500ms (可调),这时就可判断是单击还是双击。马老师程序就是这么做的。2、先按单击处理一次,如果在500ms (可调)内又一次单击,则继续执行双击。这时有个问题,如果单击和双击无关,那么第一次单击就是多余的,完全可以说是错误的。windows 取了个巧,定义单击是选定,双击是打开,两个操作具有逻辑上的延续性,所以显得没有延时。 如果你定义单击是删除,双击打开,你看看有没有延时。回复举报 发表于 2011-8-25 23:31:06 |只看该作者29楼mark 回复举报 发表于 2011-8-26 00:03:05 |只看该作者30楼
回复【27楼】packer
25楼的兄弟,你没理解马老师的意思
当你第一次单击之后,神仙也不知道这是单击还是双击
这时有2种处理方法
1、等待500ms (可调),这时就可判断是单击还是双击。马老师程序就是这么做的。
5501501
主题好友积分
金牌会员
莫元
1501发消息
jielove2003
901012
主题好友积分
金牌会员
莫元1023
发消息
surf_131
3201211
主题好友积分
金牌会员
莫元1105
发消息
machao 2、先按单击处理一次,如果在500ms (可调)内又一次单击,则继续执行双击。这时有个问题,如果单击和双击无关,那么第一次单击就是多余的,完全可以说是错误的。windows 取了个巧,定义单击是选定,双击是打开,两个操作具有逻辑上的延续性,所以显得没有延时。 如果你定义单击是删除,双击打开,你看看有没有延时。-----------------------------------------------------------------------你没有理解我的意思而已。我并不是说马老师这样的做法是错误的,因为要判断双击必须要等待500ms(可调) ,但马老师现在这样的处理方法使得对于一个需要单击事件的应用必须等到500ms 以后才能有响应,这就是2楼兄弟说的500ms 的延迟,太迟钝了。当然,如果对于单击和双击同一个按键定义完全截然不同的功能这个500ms 的延迟就是必须付出的代价了,不过我认为这样的功能定义实在是太不人性化了,需要用户来学习适应并不是一个优秀的人机交互设计。windows 鼠标双击的事件机制不用于马老师这里的处理方式,马老师对于双击事件是吃掉了前面的单击,而windows 是仍然将前面的单击事件放到消息队列里面。“单击--长时间--单击”动作序列在windows 里是这样的消息: down、 up、 down、 up“单击--短时间--单击”动作序列在windows 里是这样的消息:down 、up 、double_down、up ,马老师的方法是: double_down回复举报 发表于 2011-8-26 00:24:20 |只看该作者31楼学习回复举报 发表于 2011-8-26 00:28:31 |只看该作者32楼回复【29楼】ifree64 “单击--长时间--单击”动作序列在windows 里是这样的消息: down、 up、 down、 up“单击--短时间--单击”动作序列在windows 里是这样的消息:down 、up 、double_down、up ,马老师的方法是: double_down -----------------------------------------------------------------------单击(短)应该是 down、 up、nodown......... 长按是down 、noup......... 双击是 down、 up、double_down.........另外说明下我用“单击+长按”做的东西,是调整时间(小时、分等)的某一位。单击时该位数值循环步进。如果增加双击操作,可以增添一个反向循环步进,或者-2操作。比如,8点单击调到9点,双击就-2,回到7点。但是这之后的逻辑处理比较麻烦,于是忽略双击。我感觉单键操作在lz 指示的方向上,可以发展出例如莫尔斯电码的自动识别等等应用来。回复举报 发表于 2011-8-26 02:14:06 |只看该作者33楼
回复【26楼】packer
回复【24楼】kihell 红舞林檬浩
为什么 每次进入子函数都要把
key_state = 0呢
unsigned char key_driver(void)
{
static unsigned char key_state = key_state_0, key_time = 0;
-----------------------------------------------------------------------
20709568
主题好友积分
版主
莫元
9562
发消息
machao
20709568
主题好友积分
版主没用c 写过程序,只用汇编的人说说我的理解,望指正 定义为static 类型,只在系统初始化赋此值 注意下一句就没定义成static ,所以key_return = n_key每次调用都会被执行 这也是我画状态图时很犹豫的地方,不知该如何表示-----------------------------------------------------------------------意思是对的。 在C 中,static 定义的变量如同一个全局变量,在整个程序中,该变量(内存)一直存在。与全局(在所有函数外定义的)变量的不同处有2点:1。此变量具备局部变量的特点,只能在本定义的函数中使用,其它函数中则不能对起操作。2。由于1的特点,可以在另外的函数中定义一个相同名称的static 类型变量,此时尽管两个变量“同名”,但是实际是不同的两个变量,分别永久占用2个不同的内存单元。 所以对于static 变量,在调用第1次调用定义此变量的函数时,会在RAM 中分配一个地址,并赋初值。当定义此变量的函数返回后,该变量所占用的RAM 并不释放,仍旧保持原来的数据,但对于其它函数,这个变量是“隐身”的(类似C++中的私有变量)。当再1次调用定义此变量的函数时,由于该变量已经存在了,所以就不会再次被赋初值的。 而通常在一个函数中定义的变量,属于局部变量,每次调用定义此变量的函数时,就会在RAM 中分配一个地址,并赋一个初值。当定义此变量的函数返回后,该变量所占用的RAM 就被释放掉了,此时这个变量是“不存在”的。如果上面的解释还是不理解的话,下面给一个表浅的解释: 在C 语言中,如果在定义变量的定义语句中同时赋值,表示系统应该在为该变量分配内存空间后,赋一个规定的初值(如果定义变量语句中没有赋值,那么其初值是不定的。但在多数系统中通常为0)。 那么如何理解下面的2个变量定义呢: unsigned char key_driver(void) { static unsigned char key_state = key_state_0; unsigned char key_return = N_key; ........ key_state是static 类型,在第1次调用函数时,需要为其分配内存单元,赋初值。以后该变量永久保持,因此不是每次调用都被赋初值的(不是每次调用都要为其分配内存单元的!) 而key_return就是一个局部变量,每次调用函数时,需要为其分配内存单元,要赋初值。而函数返回后,该变量取消了,对应分配的内存释放掉。(是每次调用都要为其分配内存单元的,所以每次要赋初值!)=========================================在20几年前,给学生上C 语言。考试中有这样的题目: 1。什么是全局变量、局部变量、静态变量、动态变量?各有什么特点? 2。请说明和解释C 语言中以下定义的3个变量属于什么性质的变量: unsigned char key_time = 0; unsigned char key_driver(void) { static unsigned char key_state = key_state_0; unsigned char key_return = N_key; ........ 3。总结、归纳出在C 中如何正确定义和使用变量,说明为什么。 。。。。。 现在,这样的题目不敢出了。不仅学生回答不出,而且就是许多教C 的教师也说不明白(实际上,还有细分:比如:静态局部、静态外部等)。给点提示:在上例中key_time是全局静态变量,key_state是局部静态变量,key_return是局部动态变量。它们之间的区别请仔细体会。 难一点的思考:有不有全局动态变量?如果有的话,是什么形式的,如何形成?为什么和什么情况下要使用全局动态变量?回复举报 发表于 2011-8-26 03:09:54 |只看该作者34楼回复【29楼】ifree64 回复【27楼】packer 25楼的兄弟,你没理解马老师的意思 当你第一次单击之后,神仙也不知道这是单击还是双击 这时有2种处理方法 1、等待500ms (可调),这时就可判断是单击还是双击。马老师程序就是这么做的。 2、先按单击处理一次,如果在500ms (可调)内又一次单击,则继续执行双击。这时有个问题,如果单击和双击无关,那么第一次单击就是多余的,完全可以说是错误的。windows 取了个巧,定义单击是选定,双击是打开,两个操作具有逻辑上的延续性,所以显得没有延时。 如果你定义单击是删除,双击打开,你看看有没有延时。 ----------------------------------------------------------------------- 你没有理解我的意思而已。 我并不是说马老师这样的做法是错误的,因为要判断双击必须要等待500ms(可调)......
莫元
9562
发消息
ww1228
150191
主题好友积分
注册会员
莫元163
发消息-----------------------------------------------------------------------两位无需争论了,都静下来仔细琢磨,我回答下面2个问题:1。利用状态机的方式,可以提供每次按键的down 、up 状态、本次down - up的间隔、上次up-本次down 的间隔。有了这些,你的上层可以做各种的分析。实现W 里面鼠标左键的所有功能没有问题的。 只是我的题目定义的单击、双击操作与W 鼠标指向打开一个文件的单击、双击有区别: W鼠标双击一个文件,包括2个动作:1-选中该文件,2-打开文件,单击一个文件的动作是选中该文件。由于双击的第1个动作与单击相同,所以其双击操作的第1次单击不需要等待,可以马上响应的。 如果双击的动作中开始部分与单击动作不同,单击的响应一定要滞后的,当然这个滞后时间可以调整到适合。 2。至于“这样的功能定义实在是太不人性化了,需要用户来学习适应并不是一个优秀的人机交互设计”,则是寡闻了。这个不是我发明创造的,你的手边就有这样的“实在是太不人性化”的“不是一个优秀的人机交互设计”的最有力证明:手机!! 我在6楼已经给出了实际的东西: -------------------------------------------------------------------------------------------------------- 手机有吧。打开进入短信编辑状态,设置输入方式为英文,然后操作一个键单击、双击、长按,看屏幕输入有何变化。 但是你在打电话,输入电话号码的时候,此时只响应单击,和长按了。单击就是在释放后响应的。双击此时是两次单击。 -------------------------------------------------------------------------------------------------------- 应该先去证明一下,而后再发表意见。如果你的手机没有按键键盘,那么也应该找一个体会一下。 请不要说,因为手机的键盘是“实在是太不人性化”的“不是一个优秀的人机交互设计” ,所以IPHONE 取消了键盘,用手写了。现实中大量的电子设备和仪器,并没有屏幕、鼠标、手写的交互,就是简单的LED 灯和按键,所以多功能按键到处都有的。 看个最简单的例子,到商店找个电子手表,它就2-3个按键,你设置一下日期和时间,体会一下吧。至少你能发现一个按键有短按和长按连_发的功能。如果你认为它“实在是太不人性化”的“不是一个优秀的人机交互设计”,那么你如何设计?为电子表增加一个鼠标接口?================================================================================================================== 现在的系统,成本核算非常重要。你可以增加一个或几个键,使得“人机交互人性化”,单成本也是要增加的。对于有些不常用、特殊的功能,通常使用多功能按键完成,而常用,经常的操作,尽量简单,不用多功能的按键。这是综合平衡的办法。 东西是死的,人是活的。只要你有能力,就能设计出合理的交互方式。 还是讲手表上的一个键,如果是用户在查询时间方式工作,希望这个按键只有单击的单一功能,响应要快,而用户在设置时间方式工作,希望这个按键是多功能的,有单击和长按连_发的功能,但此时单击的响应要慢点了。 如何处理这个矛盾? 这个也简单呀。你写2套低层的驱动,一套就是扫描按键的按下,马上响应,另一套是需要等待的。然后增加一个状态判断,如果是上层在查询时间方式,那么使用前一套扫描按键,反映肯定快,如果上层在设置时间方式,就使用第2套扫描按键,此时单击响应要慢一点。这样不就平衡了吗?谁一天到晚去设置日期和时间? 还不是大状态机套小状态机吗? ================================================================================================================== 在我编写的教材中,已经说明状态机是系统分析的一种方法,不是我发明的。采用状态机的按键设计也不是我率先提出的。都是早就有的东西。我只是拿按键这个小的例子,引出状态机设计的方法,让大家去体会,并能掌握这个方法去使用在其它的地方,就是一个系统主工作方式,通常都是可以用状态机的思路来进行分析和设计,并实现的。回复举报 发表于 2011-8-26 08:49:23 |只看该作者35楼学习了
回复举报
ifree64 发表于 2011-8-26 08:54:21 |只看该作者36楼5501501
主题好友积分
金牌会员
莫元
1501发消息
ifree64
5501501
主题好友积分
金牌会员
莫元1501
发消息
packer
20542
主题好友积分
高级会员
莫元542
发消息
lexuezhitu 回复【33楼】machao 我在6楼已经给出了实际的东西: -------------------------------------------------------------------------------------------------------- 手机有吧。打开进入短信编辑状态,设置输入方式为英文,然后操作一个键单击、双击、长按,看屏幕输入有何变化。 但是你在打电话,输入电话号码的时候,此时只响应单击,和长按了。单击就是在释放后响应的。双击此时是两次单击。 -------------------------------------------------------------------------------------------------------- 应该先去证明一下,而后再发表意见。如果你的手机没有按键键盘,那么也应该找一个体会一下。 -----------------------------------------------------------------------状态机的思想我也是非常喜欢用的,并且很好用。昨天发帖子时因为网络故障,关于人机交互这方面我的意思表达得并不全面,我的意思不是说使用单击和双击就是差的人机交互,而是如果一个按键的功能单击和双击风马牛不相及,甚至逻辑矛盾,那么就是差的人机交互设计。比如单击用于删除、双击打开,那么在需要打开文件、或者删除文件时,就必然会发生一些单击、双击的错误操作。而像windows 的资源管理器那样对单击、双击的具有“逻辑延续性”的功能定义正正是需要认真学习的人机交互功能设计。刚才也特意试了下我手中的山寨手机在英文输入下的按键处理,可能这个手机功能实在太山寨了,没有长按和双击的支持,也许其他手机有这样的功能吧。不过,我也仔细想了一下手机如何利用非常少的按键实现众多功能的,貌似问题的关键不是单击、双击、长按。而是“确定”、“取消”两个按键在不同时候有不同功能,通过“确定”、“取消”、“上”、“下”这几个功能键构成了一个菜单系统。是不是这种方式才是更好的利用少量按键实现多种功能的方法呢(这里也用一个状态机来规定不同状态下同一按键的功能)?当然适当的定义长按和双击可以带来更加灵活的变化,不过我比较反对对同一个键的不同按的方式定义“逻辑不相关”的功能。比如“+”键,单击加一次,长按加十次,按着不放再连_发“+”的功能,应该就是一种非常“直白" 的功能定义,但如果把”+“键,单击定义为加,双击定义为减,恐怕就不是一个很好的功能第一。PS :我前面关于windows 对鼠标单击、双击的处理提到windows 的消息机制,这个是windows 系统很底层的驱动行为;不知为什么大家都用windows 资源管理器的行为来讨论windows 对鼠标单击、双击的处理。windows 的鼠标驱动和windows 资源管理器之间的关系正如马老师贴出来的按键驱动与上层应用之间的关系。回复举报 发表于 2011-8-26 09:15:15 |只看该作者37楼回复【33楼】machao W 鼠标双击一个文件,包括2个动作:1-选中该文件,2-打开文件,单击一个文件的动作是选中该文件。由于双击的第1个动作与单击相同,所以其双击操作的第1次单击不需要等待,可以马上响应的。 这个也简单呀。你写2套低层的驱动,一套就是扫描按键的按下,马上响应,另一套是需要等待的。然后增加一个状态判断,如果是上层在查询时间方式,那么使用前一套扫描按键,反映肯定快,如果上层在设置时间方式,就使用第2套扫描按键,此时单击响应要慢一点。这样不就平衡了吗?谁一天到晚去设置日期和时间? -----------------------------------------------------------------------请问马老师,如何用2套底层驱动切换的方式实现类似windows 资源管理器对鼠标单双击功能呢?我觉得这个问题的答案才是windows 鼠标驱动和您的方式在本质上的区别。回复举报 发表于 2011-8-26 09:18:02 |只看该作者38楼马老师这句话太对了“现在的系统,成本核算非常重要。”我经常被要求只给4个键,而要完成10种以上功能操作,我倒是想学explorer ,实在学不来回复举报 发表于 2011-8-26 09:22:53 |只看该作者39楼
学习了!
2
主题
新手上路0好友27积分
莫元
发消息27
回复
cjr82123 发表于 2011-8-26 10:01:33 |只看该作者
每次见马老师都有收获,谢谢马老师!
自从用了状态机后,腰也不疼了,腿也不酸了,走路也更有劲了。举报40楼
22
主题
中级会员0好友483积分
莫元
发消息480
回复举报
返回列表123456781 / 8 页下一页
高级模式
您需要登录后才可以回帖 登录 | 注册
发表回复 回帖后跳转到最后一页
阿莫电子论坛, 原" 中国电子开发网"
2004-2012 www.amobbs.com , 原www.ourdev.cn, 原www.ouravr.com 手机版|Archiver |阿莫电子论坛(原中国电子开发网) ( 粤ICP 备09047143号 )GMT+8, 2012-8-3 15:04 , Processed in 0.065857 second(s), 7 queries , Memcache On.
用户名密码
自动登录登录
找回密码 注册
首页全部贴汇总请输入搜索内容
技术贴汇总非技术汇总帮助无图快速版搜索
搜索
阿莫电子邮购
热搜:雕刻机阿莫淘金春风电源
快捷导航
论坛首页开源已完成马潮AVR 题目:多功能按键设计。利用一个I/O口,接一个按键,实 ...
返回列表
1
2
3
4
5
6
7
8
1
/ 8 页
下一页
查看: 11538|回复: 292
题目:多功能按键设计。利用一个I/O口,接一个按键,实现3功能操作:单击 + 双击 + 长按。 [复制链接]
发表于 2011-8-23 18:12:42 |只看该作者 |倒序浏览
1楼
电梯直达
machao
oB
20709568主题好友
积分
版主
莫元9562
发消息
BS
阿
莫
题目:多功能按键设计。利用一个I/O口,接一个按键,实现3功能操作:单击 + 双击 + 长按。
============================================================================ 用户基本操作定义:
1。短按操作:按键按下,按下时间1s,属于一次长按操作
在正常0.5s 内无按键操作为启始按键扫描条件下,扫描按键将产生以下3种按键事件: 1。长按事件:任何1次出现的长按操作都属于长按事件 2。单击事件:1次短按操作后,间隔0.5内没有短按操作
3。双击事件:2次短按操作间隔时间
1。短按操作和长按操作间隔
对按键操作者的建议:
由于按键的多功能性质,建议操作者每次在单击/长按/双击按键事件发生后,隔0.5s 后再进行下一次的按键操作。因为在特别操作情况下,程序是保证按定义进行判断和处理的,主要是怕操作者自己记不清楚导致操作失误。
对软件设计者的要求:
1。应该全面进行分析,给出严格定义和判断条件,如上所示。如果自己都不清楚,你的设计出的系统就不稳定,不可靠。 2。在1的基础上,编写出符合要求的程序,并进行全面测试。
/*=============
低层按键(I/0)扫描函数,即低层按键设备驱动,只返回无键、短按和长按。具体双击不在此处判断。参考本人教材的例9-1,稍微有变化。教材中为连_发。
===============*/
#define key_input PIND.7 // 按键输入口 #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
unsigned char key_driver(void) {
static unsigned char key_state = key_state_0, key_time = 0; unsigned char key_press, key_return = N_key; key_press = key_input; // 读按键I/O电平
switch (key_state) {
case key_state_0: // 按键初始态
if (!key_press) key_state = key_state_1; // 键被按下,状态转换到按键消抖和确认状态 break;
case key_state_1: // 按键消抖与确认态 if (!key_press) {
key_time = 0; //
key_state = key_state_2; // 按键仍然处于按下,消抖完成,状态转换到按下键时间的计时状态,但返回的还是无键事件 } else
key_state = key_state_0; // 按键已抬起,转换到按键初始态。此处完成和实现软件消抖,其实按键的按下和释放都在此消抖的。 break;
case key_state_2: if(key_press) {
key_return = S_key; // 此时按键释放,说明是产生一次短操作,回送S_key key_state = key_state_0; // 转换到按键初始态 }
else if (++key_time >= 100) // 继续按下,计时加10ms (10ms 为本函数循环执行间隔) {
key_return = L_key; // 按下时间>1000ms,此按键为长按操作,返回长键事件 key_state = key_state_3; // 转换到等待按键释放状态 }
break;
case key_state_3: // 等待按键释放状态,此状态只返回无按键事件 if (key_press) key_state = key_state_0; //按键已释放,转换到按键初始态 break; }
return key_return; }
/*=============
中间层按键处理函数,调用低层函数一次,处理双击事件的判断,返回上层正确的无键、单键、双键、长键4个按键事件。 本函数由上层循环调用,间隔10ms ===============*/
unsigned char key_read(void) {
static unsigned char key_m = key_state_0, key_time_1 = 0; unsigned char key_return = N_key,key_temp;
key_temp = key_driver();
switch(key_m) {
case key_state_0:
if (key_temp == S_key ) {
key_time_1 = 0; // 第1次单击,不返回,到下个状态判断后面是否出现双击 key_m = key_state_1; } else
key_return = key_temp; // 对于无键、长键,返回原事件 break;
case key_state_1:
if (key_temp == S_key) // 又一次单击(间隔肯定
key_return = D_key; // 返回双击键事件,回初始状态 key_m = key_state_0; }
else
{ // 这里500ms 内肯定读到的都是无键事件,因为长键>1000ms,在1s 前低层返回的都是无键 if(++key_time_1 >= 50)
{
key_return = S_key; // 500ms内没有再次出现单键事件,返回上一次的单键事件 key_m = key_state_0; // 返回初始状态 } }
break; }
return key_return; }
下面,根据程序分析按键事件的反映时间: 1。对于长键,按下超过1s 马上响应,反映最快
2。对于双键,第2次按键释放后马上得到反映。
3。对于单键,释放后延时拖后500ms 才能响应,反映最慢。这个与需要判断后面是否有双击操作有关,只能这样。实际应用中,可以调整两次单击间隔时间定义,比如为300ms ,这样单击的响应回快一点,单按键操作人员需要加快按键的操作过程。如果产品是针对老年人的,这个时间
yuzr
不易太短,因为年纪大的人,反映和动作都比较慢。
当然,上面两段可以合在一起。我这样做的目的,是为了可以方便的扩展为N 击(当然,需要做修改)。可是最底层的就是最基本的操作处理短按和长按,不用改动的。至于双击,还是N 击,在中间层处理。这就是程序设计中分层结构的优点。 测试代码环境如下:
interrupt [TIM0_COMP] void timer0_comp_isr(void) // 定时器10ms 中断服务 {
time_10ms_ok = 1; }
main(viod) { ......... while {
if (time_10ms_ok) //每10ms 执行一次, {
time_10ms_ok =0;
key = key_read(); //《====== 10ms一次调用按键中间层函数,根据返回键值,点亮不同的LED 灯,全面测试按键操作是否正常
if (key == L_key)
........//点亮A_LED,关闭B_LED和C_LED else if(key == D_key)
........//点亮B_LED,关闭A_LED和C_LED else if(key == S_key)
........//点亮C_LED,关闭A_LED和B_LED } } }
=================================================
通过以上这个看似简单的按键,看在应用中如何变化,以及如何在实际产品中全面、可靠的进行设计。
=======================================================================================================后续:
这个是一个网友要求我做的东西,他买了我编写的教材,学习了里面的状态机按键设计,但还是不能灵活的使用。我提出让一些有兴趣的朋友做一下,大家讨论,(见http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=4971785&bbs_page_no=1&bbs_id=1003,28楼),但是很少人给出满意的回答。甚至是这样的回答:“晕,参加电设的也有很多强人,虽然不一定是精英,但还是很有实力的,这种题目很多人都很早就会做了,没必要当作电设的训练题。(见该贴30楼的回答)”。这个如同我去年挑战一个北大高才生一样,真本事没有,就是嘴硬。
既然别人不感“兴趣”,我编写代码,实现这个简单的多功能按键。这也是对这位购买我编写书的朋友的一种答谢吧。 写完后,还想扩展一点,发点“偏见”如下:
相比国际上的一些品牌产品,国内的很多东西都做不精。其中系统分析和软件设计占有重要的因素。其实不是不想做的好,而是根本没有能力做好!
如上这样一个简单的多功能按键,都分析不透,设计不出好的代码,就不要谈上天下海的吧。D 车追尾就是发生了特殊情况,设计中根本没有考虑周全,加上工作人员的不负责,产生如此大的灾难。
最近频繁出现的塌桥、电梯事故、火车出事,都是上天对现在浮躁社会的报应。我们都抱怨别人不负责,浮躁,那么你自己呢?
别人,别的行业我没有资格讲不好,但是对于正在学习的本专业大学生,尤其是要参加全国大学生电子设计大赛的学生,你做这个题目能拿多少分?评估一下有多少能力和水平?
实际上,现在的全国大学生电子设计大赛也变成是一个浮躁的产物,学校和学生都指望它能贴金,对于真正培养和锻炼人的目的和作用,实际上只是挂在前面遮羞布了。
本主题由 machao 于 2012-4-3 12:18 解除置顶
收藏54回复
举报 发表于 2011-8-23 18:28:38 |只看该作者
2楼
yuzr 发表于 2011-8-23 18:28:38 |只看该作者401092主题好友
积分
金牌会员
莫元
1088
发消息
surf_131
3201211主题好友
积分
金牌会员
莫元1105
发消息
linghu2
2702992主题好友积分
金牌会员令狐二中
莫元2920
发消息
ruizhixing
mark
回复
举报 发表于 2011-8-23 18:46:39 |只看该作者3楼
很有意义的帖子。
我这几天在PIC 平台上也考虑过同样的东西,但是今天放弃了三种不同键识别的办法,改用一长一短两个键实现需要的功能。是在定时中断中设置几个变量来识别长短键。这样,短键可以在抬键后一个中断周期内快速响应,长键则在按下后3秒左右才开始响应,并能用查询法等待上次长键结束。
如果允许的双击间隔是500ms ,则判断单点击要滞后500ms 以上,太迟钝了。
回复
举报 发表于 2011-8-23 19:03:14 |只看该作者4楼
如果连这么简单的东东都写不出来, 参加电设就是浮云
回复
举报 发表于 2011-8-23 19:08:43 |只看该作者
5楼
“实际上,现在的全国大学生电子设计大赛也变成是一个浮躁的产物,学校和学生都指望它能贴金,对于真正培养和锻炼人的目的和作用,实际上只是挂在前面遮羞布了。 ”
/***********************************************************************************************************/
最近看了一个帖子,说电设与高考的对比.... 百度上搜查“电子设计大赛 高考”。看来我得好好戒除自己的浮躁心态了...
11主题注册会员
0好友94积分
莫元
发消息
94
回复
ifree64
发表于 2011-8-23 19:19:45 |只看该作者
举报6楼
5501501主题好友
积分
金牌会员
莫元1501
发消息
machao
20709568主题好友
积分
版主
莫元9562
发消息
machao
20709568主题好友
积分
版主
莫元
9562
回复【2楼】surf_131 很有意义的帖子。
我这几天在pic 平台上也考虑过同样的东西,但是今天放弃了三种不同键识别的办法,改用一长一短两个键实现需要的功能。是在定时中断中设置几个变量来识别长短键。这样,短键可以在抬键后一个中断周期内快速响应,长键则在按下后3秒左右才开始响应,并能用查询法等待上次长键结束。
如果允许的双击间隔是500ms ,则判断单点击要滞后500ms 以上,太迟钝了。-----------------------------------------------------------------------在windows 平台上,鼠标双击事件的顺序大致为键按下、键抬起、双击键按下;这样不会出现单击滞后500ms 的问题了。
回复
举报 发表于 2011-8-23 19:44:02 |只看该作者
7楼
回复【2楼】surf_131 很有意义的帖子。
我这几天在pic 平台上也考虑过同样的东西,但是今天放弃了三种不同键识别的办法,改用一长一短两个键实现需要的功能。是在定时中断中设置几个变量来识别长短键。这样,短键可以在抬键后一个中断周期内快速响应,长键则在按下后3秒左右才开始响应,并能用查询法等待上次长键结束。
如果允许的双击间隔是500ms ,则判断单点击要滞后500ms 以上,太迟钝了。-----------------------------------------------------------------------手机有吧。打开进入短信编辑状态,设置输入方式为英文,然后操作一个键单击、双击、长按,看屏幕输入有何变化。但是你在打电话,输入电话号码的时候,此时只响应单击,和长按了。单击就是在释放后响应的。双击此时是两次单击。在不同的工作状态,可以对不同按键操作做不同的处理。掌握了这些,就能设计出好的系统。
回复
举报 发表于 2011-8-23 20:18:49 |只看该作者8楼
回复【5楼】ifree64
-----------------------------------------------------------------------
在windows 平台上,鼠标双击事件的顺序大致为键按下、键抬起、双击键按下;这样不会出现单击滞后500ms 的问题了。 -----------------------------------------------------------------------你分析的不对。
在windows 平台上,鼠标双击事件为左键快速按两下,之间还是有时间间隔定义的。单其定义不同:
我们以双击打开文件夹中一个WORD 文件为例:
将鼠标运动指在这个文件上,然后单击,表示选中该文件,如果快速双击,则表示选中该文件,并打开。你可以测试一下,如果将鼠标运动指在这个文件上,然后单击,过长点时间再次单击,是不会打开文件的。
所以,此时windows 平台的定义为:
发消息
所以,此时windows 平台的定义为:
第1次单击为选中该文件,如果第2次单击的时间与前面选择文件的单击间隔小于一定的时间,就自动打开该文件。因此,它的第一次单击不需要等待,可以马上动作。只是判断第2次单击与此次的间隔,如果小,属于双击,自动打开文件,如果长,则仍旧表示选择该文件。 而在嵌入式系统中,有时没有屏幕光标的辅助,这样处理反而不方便。
在这个题目开始,我已经定义的操作过程。如果按windows 平台上的鼠标双击事件,也是容易做到的,但此时“双击”的定义就不同了。
另外,windows 平台上的鼠标很少处理长按。如果有长按,那么单击就不可能马上被响应,必须等待到释放,看按下的时间才能判断是单击或长按。
先仔细体会一下,操作操作,再提出你的看法。我的贴子,不是一般的肤浅东西。
应一句老话,没有金刚钻,就不会揽这些瓷器活。否则我也不敢吹嘘我编写的教材。出版此类教材的教授多了,有几个真正设计产品,亲自编写代码的?都是理论加肤浅和不实用的代码。
不好意思,晚上灌了的啤酒,说酒话。不过,酒话往往是真话和实话。
回复
举报9楼
HQkiller1 发表于 2011-8-23 22:16:15 |只看该作者
004主题好友积分
游客莫元
4
发消息
HQkiller1
004主题好友
积分
游客莫元4
发消息
packer
20542主题好友
积分
高级会员
莫元542
发消息
HQkiller1
老师,阅读你的帖子和教材我获益匪浅,今天我在看你出版AVR 教材,对于你的教材中的第十五章:串行SPI 接口应用 中的例15_1的源程序存在一下疑问:
基于74HC164并利用SPI 口实现8路并口输出的扩展(原书P437页)以下给出我存在疑问的源程序的一部分:#difine SPIF 7....
while (!(SPSR&(1
//SPI初始化SPCR=0x50;SPSR=0x01;
您在书中while 语句后的注释为“等待SPI 完成”但是我觉得你的程序好像不能实现这个功能
首先你把SPIF 定义为7(0000_0111)让后与SPSR (0000_0001)位与,在while 循环中只循环了5次就跳出了while 循环,而要传送的是一个字节的数据(8位)所以我觉得你的程序在还没有将8位数据串行传输完就已经去执行下面的显示语句了,好像不能达到要求也有可能是我没看懂马老师精妙的程序,还望不吝赐教
回复
举报 发表于 2011-8-23 22:27:32 |只看该作者
10楼
马老师,在AVR 教材中第十五章:串行SPI 接口应用,例 15.2中您用采用完结A/D的方法实现数字万用表的功能,可是ATmega16只是8位的单片机,请问用没用什么办法用你的AVR 开发板实现十二位的A/D转换呢?
我用的是TI 的TLV2543芯片,是十二位的D/A芯片,用你讲的SPI 的办法好像不行,应为ISP 数据寄存器只有8位,无法存储12位转化结果
回复
举报 发表于 2011-8-23 22:39:42 |只看该作者11楼
受益匪浅。不大会画状态图,献丑了。
根据马老师程序画的状态图 (原文件名:machao.JPG)
回复
举报 发表于 2011-8-23 22:52:35 |只看该作者
12楼
呵呵,用马老师的AVR 实验板已经成功实现了以上按键要求
0主题游客莫元
0好友4积分
4
发消息
回复
roy2002
发表于 2011-8-23 23:02:09 |只看该作者举报13楼
290653主题好友积分
高级会员
莫元626
发消息
stefgq
300868主题好友积分
高级会员
莫元868
发消息
elecfun
5101660主题好友积分
金牌会员
莫元1671
发消息
果断MARK
回复
举报 发表于 2011-8-23 23:30:36 |只看该作者14楼
很好
回复
举报 发表于 2011-8-24 01:14:34 |只看该作者
15楼
刚在WIN7平台上试了下鼠标左键:
____-_----- 即短按+短间隔+长按,在长按还没有松开前系统已经认为是双击。____---_-__ 即长按+短间隔+短按,判定为两个(间隔较长的)单击。
这样看来,WIN7上判断鼠标左键按下,是有个超时处理机制。超过一定时间即认为按键已按下。
鼠标右键:
在某文件上右键长按,松开后才会显示文件右键相关菜单项。如果右键按下期间鼠标移动过,则会显示 到当前位置 相关菜单。如果你的浏览器支持右键动作,也可以试试(小心,别执行了关闭当前窗口的动作~~)。
然后进行另外几项测试:
1. 单击选中某个文件,然后在文件名处单击(即修改文件名),会等大概500ms 的样子,才进入修改主文件名状态。
2. 单击选中某个文件,然后在文件名处双击,可以看到,文件会被直接打开而不会进入文件名修改状态。
3. 就在你现在看到的文字位置处,单击,然后间隔稍长,再单击(些过程实质为双击,间隔稍长是为了更清楚的看到过程), 你会看到光标在第一次单击时就移过来了,第二次单击时就是双击选中的效果。
4. 打开记事本,鼠标移到“文件”菜单项上,然后双击。你会看到依然是单击的效果,显示相关下拉菜单。
5. 打开记事本,单击“文件”菜单项,显示相关下拉菜单;第二次单击“文件”菜单项,下拉菜单收回;第三次单击“文件”, 下拉菜单再次显示。
6. 打开记事本,单击“文件”菜单项,显示相关下拉菜单,然后双击菜单(如 文件),你会看到相关下拉菜单项会“刷新”一 下(是不是5中的收回再显示呢?)。
7. 打开IE8,如果隐藏了菜单栏按 Alt 键,以显示。双击“文件”,可以看到相关下拉菜单显示后又立即收回(是不是两个单击?)。8. 双击IE8工具栏上的“页面”按钮 或者 Chrome 右上角的设置按钮,可以看到相关下拉菜单显示后又立即收回。
综上7条,是不是可以看出,WIN7上不同的应用程序对单击、双击的操作不同?
回复
kenluo
发表于 2011-8-24 09:08:56 |只看该作者举报
16
楼
140338主题好友积分
游客莫元
338
发消息
kingsabbit
4301589主题好友积分
金牌会员
莫元1540
发消息
surf_131
3201211主题好友
积分
金牌会员
莫元1105
发消息
楼主, 按键方面处理的方法不错
回复
举报 发表于 2011-8-24 10:21:58 |只看该作者17楼
看过类似的做法, 但没真正写过
回复
举报 发表于 2011-8-24 10:59:54 |只看该作者18楼
长键则在按下后3秒左右才开始响应,----------------------------------------今天利用这个长键状态做了个延迟灯,一旦有键按下就点燃。发现延时不是3秒,而是2秒。这让那个延迟略显仓促。不过暂时不改了。当初是为了加快按键响应把定时器间隔减小了。特此说明。
回复举报
whhityang 发表于 2011-8-24 11:25:01 |只看该作者19楼
360417主题好友积分
中级会员
莫元
405
发消息
zjy9430
00326主题好友积分
中级会员
莫元
323
发消息
stoneee 150139主题好友积分
注册会员
莫元136
发消息
farmer
40238主题好友
积分
中级会员
莫元238
发消息
看那个帖子时想着随便写写就很好写出双击、长按的,只是脑子里过了下大概写法就过去了。现在再看马老师的写法,发现想法和实现出来还真是有点差距的,尤其是完美的实现。又一次见识到了马老师严谨细致的态度,受教了。
回复
举报 发表于 2011-8-24 11:32:43 |只看该作者20楼
参考一下
回复举报
发表于 2011-8-24 14:44:53 |只看该作者21楼
按键状态机,好用!
回复
举报 发表于 2011-8-24 16:39:53 |只看该作者22楼
按键状态机,好用!
回复
dongzhiqing
发表于 2011-8-24 16:42:35 |只看该作者举报
23
楼
420620主题好友
积分
高级会员
莫元620
发消息
HQkiller1004主题好友积分
游客莫元
4
发消息
kihell
80235主题好友积分
中级会员
莫元233
发消息
ifree64
5501501主题好友积分
金牌会员
顶一下。
回复举报
发表于 2011-8-24 16:56:02 |只看该作者24楼
不要灌水,有意义么
回复【22楼】dongzhiqing
-----------------------------------------------------------------------
回复
举报 发表于 2011-8-25 21:41:32 |只看该作者25楼
为什么 每次进入子函数都要把
key_state = 0呢
unsigned char key_driver(void) {
static unsigned char key_state = key_state_0, key_time = 0;
回复
举报 发表于 2011-8-25 21:57:04 |只看该作者26楼
回复【7楼】machao
回复【5楼】ifree64
-----------------------------------------------------------------------
在windows 平台上,鼠标双击事件的顺序大致为键按下、键抬起、双击键按下;这样不会出现单击滞后500ms 的问题了。 -----------------------------------------------------------------------你分析的不对。
在windows 平台上,鼠标双击事件为左键快速按两下,之间还是有时间间隔定义的。单其定义不同:我们以双击打开文件夹中一个word 文件为例:
将鼠标运动指在这个文件上,然后单击,表示选中该文件,如果快速双击,则表示选中该文件,并打开。你可以测试一下,如果将鼠标运动指在这个文件上,然后单击,过长点时间再次单击,是不会打开文件的。所以,此时wi......
-----------------------------------------------------------------------
莫元
发消息1501不知马老师是否熟悉Windows 平台上的程序开发,我的话是没有错误的,请看如下这句引自MSDN 的原话(http://msdn.microsoft.com/en-us/library/ms645606(v=vs.85).aspx)
Only windows that have the CS_DBLCLKS style can receive WM_LBUTTONDBLCLK messages, which the system generates whenever theuser presses, releases, and again presses the left mouse button within the system's double-click time limit. Double-clicking the left mousebutton actually generates a sequence of four messages: WM_LBUTTONDOWN, WM_LBUTTONUP, WM_LBUTTONDBLCLK, andWM_LBUTTONUP
这就是一个双击事件并不是只有一个WM_LBUTTONDBLCLK消息,而是按照先后顺序有4个消息;至于如何对这四个消息如何处理是应用程序自己的事。
如果只需要处理单击事件,响应WM_LBUTTONDOWN消息即可,要处理双击事件,就响应WM_LBUTTONDBLCLK,这样处理单击的事件的应用程序也不会
引入500ms 的延迟,处理双击的也可得到这个双击事件。至于两次单击之间是多长的时间,这只是一个系统的参数而已。
回复
packer 发表于 2011-8-25 22:41:01 |只看该作者举报27楼20542
主题好友积分
高级会员
莫元542
发消息
packer
20542
主题好友积分
高级会员
莫元542
发消息
cne53102
110297
主题好友积分
中级会员
莫元297
发消息
ifree64回复【24楼】kihell 红舞林檬浩为什么 每次进入子函数都要把 key_state = 0呢 unsigned char key_driver(void) { static unsigned char key_state = key_state_0, key_time = 0; -----------------------------------------------------------------------没用c 写过程序,只用汇编的人说说我的理解,望指正定义为static 类型,只在系统初始化赋此值注意下一句就没定义成static ,所以key_return = N_key每次调用都会被执行这也是我画状态图时很犹豫的地方,不知该如何表示回复举报 发表于 2011-8-25 23:04:32 |只看该作者28楼25楼的兄弟,你没理解马老师的意思当你第一次单击之后,神仙也不知道这是单击还是双击这时有2种处理方法1、等待500ms (可调),这时就可判断是单击还是双击。马老师程序就是这么做的。2、先按单击处理一次,如果在500ms (可调)内又一次单击,则继续执行双击。这时有个问题,如果单击和双击无关,那么第一次单击就是多余的,完全可以说是错误的。windows 取了个巧,定义单击是选定,双击是打开,两个操作具有逻辑上的延续性,所以显得没有延时。 如果你定义单击是删除,双击打开,你看看有没有延时。回复举报 发表于 2011-8-25 23:31:06 |只看该作者29楼mark 回复举报 发表于 2011-8-26 00:03:05 |只看该作者30楼
回复【27楼】packer
25楼的兄弟,你没理解马老师的意思
当你第一次单击之后,神仙也不知道这是单击还是双击
这时有2种处理方法
1、等待500ms (可调),这时就可判断是单击还是双击。马老师程序就是这么做的。
5501501
主题好友积分
金牌会员
莫元
1501发消息
jielove2003
901012
主题好友积分
金牌会员
莫元1023
发消息
surf_131
3201211
主题好友积分
金牌会员
莫元1105
发消息
machao 2、先按单击处理一次,如果在500ms (可调)内又一次单击,则继续执行双击。这时有个问题,如果单击和双击无关,那么第一次单击就是多余的,完全可以说是错误的。windows 取了个巧,定义单击是选定,双击是打开,两个操作具有逻辑上的延续性,所以显得没有延时。 如果你定义单击是删除,双击打开,你看看有没有延时。-----------------------------------------------------------------------你没有理解我的意思而已。我并不是说马老师这样的做法是错误的,因为要判断双击必须要等待500ms(可调) ,但马老师现在这样的处理方法使得对于一个需要单击事件的应用必须等到500ms 以后才能有响应,这就是2楼兄弟说的500ms 的延迟,太迟钝了。当然,如果对于单击和双击同一个按键定义完全截然不同的功能这个500ms 的延迟就是必须付出的代价了,不过我认为这样的功能定义实在是太不人性化了,需要用户来学习适应并不是一个优秀的人机交互设计。windows 鼠标双击的事件机制不用于马老师这里的处理方式,马老师对于双击事件是吃掉了前面的单击,而windows 是仍然将前面的单击事件放到消息队列里面。“单击--长时间--单击”动作序列在windows 里是这样的消息: down、 up、 down、 up“单击--短时间--单击”动作序列在windows 里是这样的消息:down 、up 、double_down、up ,马老师的方法是: double_down回复举报 发表于 2011-8-26 00:24:20 |只看该作者31楼学习回复举报 发表于 2011-8-26 00:28:31 |只看该作者32楼回复【29楼】ifree64 “单击--长时间--单击”动作序列在windows 里是这样的消息: down、 up、 down、 up“单击--短时间--单击”动作序列在windows 里是这样的消息:down 、up 、double_down、up ,马老师的方法是: double_down -----------------------------------------------------------------------单击(短)应该是 down、 up、nodown......... 长按是down 、noup......... 双击是 down、 up、double_down.........另外说明下我用“单击+长按”做的东西,是调整时间(小时、分等)的某一位。单击时该位数值循环步进。如果增加双击操作,可以增添一个反向循环步进,或者-2操作。比如,8点单击调到9点,双击就-2,回到7点。但是这之后的逻辑处理比较麻烦,于是忽略双击。我感觉单键操作在lz 指示的方向上,可以发展出例如莫尔斯电码的自动识别等等应用来。回复举报 发表于 2011-8-26 02:14:06 |只看该作者33楼
回复【26楼】packer
回复【24楼】kihell 红舞林檬浩
为什么 每次进入子函数都要把
key_state = 0呢
unsigned char key_driver(void)
{
static unsigned char key_state = key_state_0, key_time = 0;
-----------------------------------------------------------------------
20709568
主题好友积分
版主
莫元
9562
发消息
machao
20709568
主题好友积分
版主没用c 写过程序,只用汇编的人说说我的理解,望指正 定义为static 类型,只在系统初始化赋此值 注意下一句就没定义成static ,所以key_return = n_key每次调用都会被执行 这也是我画状态图时很犹豫的地方,不知该如何表示-----------------------------------------------------------------------意思是对的。 在C 中,static 定义的变量如同一个全局变量,在整个程序中,该变量(内存)一直存在。与全局(在所有函数外定义的)变量的不同处有2点:1。此变量具备局部变量的特点,只能在本定义的函数中使用,其它函数中则不能对起操作。2。由于1的特点,可以在另外的函数中定义一个相同名称的static 类型变量,此时尽管两个变量“同名”,但是实际是不同的两个变量,分别永久占用2个不同的内存单元。 所以对于static 变量,在调用第1次调用定义此变量的函数时,会在RAM 中分配一个地址,并赋初值。当定义此变量的函数返回后,该变量所占用的RAM 并不释放,仍旧保持原来的数据,但对于其它函数,这个变量是“隐身”的(类似C++中的私有变量)。当再1次调用定义此变量的函数时,由于该变量已经存在了,所以就不会再次被赋初值的。 而通常在一个函数中定义的变量,属于局部变量,每次调用定义此变量的函数时,就会在RAM 中分配一个地址,并赋一个初值。当定义此变量的函数返回后,该变量所占用的RAM 就被释放掉了,此时这个变量是“不存在”的。如果上面的解释还是不理解的话,下面给一个表浅的解释: 在C 语言中,如果在定义变量的定义语句中同时赋值,表示系统应该在为该变量分配内存空间后,赋一个规定的初值(如果定义变量语句中没有赋值,那么其初值是不定的。但在多数系统中通常为0)。 那么如何理解下面的2个变量定义呢: unsigned char key_driver(void) { static unsigned char key_state = key_state_0; unsigned char key_return = N_key; ........ key_state是static 类型,在第1次调用函数时,需要为其分配内存单元,赋初值。以后该变量永久保持,因此不是每次调用都被赋初值的(不是每次调用都要为其分配内存单元的!) 而key_return就是一个局部变量,每次调用函数时,需要为其分配内存单元,要赋初值。而函数返回后,该变量取消了,对应分配的内存释放掉。(是每次调用都要为其分配内存单元的,所以每次要赋初值!)=========================================在20几年前,给学生上C 语言。考试中有这样的题目: 1。什么是全局变量、局部变量、静态变量、动态变量?各有什么特点? 2。请说明和解释C 语言中以下定义的3个变量属于什么性质的变量: unsigned char key_time = 0; unsigned char key_driver(void) { static unsigned char key_state = key_state_0; unsigned char key_return = N_key; ........ 3。总结、归纳出在C 中如何正确定义和使用变量,说明为什么。 。。。。。 现在,这样的题目不敢出了。不仅学生回答不出,而且就是许多教C 的教师也说不明白(实际上,还有细分:比如:静态局部、静态外部等)。给点提示:在上例中key_time是全局静态变量,key_state是局部静态变量,key_return是局部动态变量。它们之间的区别请仔细体会。 难一点的思考:有不有全局动态变量?如果有的话,是什么形式的,如何形成?为什么和什么情况下要使用全局动态变量?回复举报 发表于 2011-8-26 03:09:54 |只看该作者34楼回复【29楼】ifree64 回复【27楼】packer 25楼的兄弟,你没理解马老师的意思 当你第一次单击之后,神仙也不知道这是单击还是双击 这时有2种处理方法 1、等待500ms (可调),这时就可判断是单击还是双击。马老师程序就是这么做的。 2、先按单击处理一次,如果在500ms (可调)内又一次单击,则继续执行双击。这时有个问题,如果单击和双击无关,那么第一次单击就是多余的,完全可以说是错误的。windows 取了个巧,定义单击是选定,双击是打开,两个操作具有逻辑上的延续性,所以显得没有延时。 如果你定义单击是删除,双击打开,你看看有没有延时。 ----------------------------------------------------------------------- 你没有理解我的意思而已。 我并不是说马老师这样的做法是错误的,因为要判断双击必须要等待500ms(可调)......
莫元
9562
发消息
ww1228
150191
主题好友积分
注册会员
莫元163
发消息-----------------------------------------------------------------------两位无需争论了,都静下来仔细琢磨,我回答下面2个问题:1。利用状态机的方式,可以提供每次按键的down 、up 状态、本次down - up的间隔、上次up-本次down 的间隔。有了这些,你的上层可以做各种的分析。实现W 里面鼠标左键的所有功能没有问题的。 只是我的题目定义的单击、双击操作与W 鼠标指向打开一个文件的单击、双击有区别: W鼠标双击一个文件,包括2个动作:1-选中该文件,2-打开文件,单击一个文件的动作是选中该文件。由于双击的第1个动作与单击相同,所以其双击操作的第1次单击不需要等待,可以马上响应的。 如果双击的动作中开始部分与单击动作不同,单击的响应一定要滞后的,当然这个滞后时间可以调整到适合。 2。至于“这样的功能定义实在是太不人性化了,需要用户来学习适应并不是一个优秀的人机交互设计”,则是寡闻了。这个不是我发明创造的,你的手边就有这样的“实在是太不人性化”的“不是一个优秀的人机交互设计”的最有力证明:手机!! 我在6楼已经给出了实际的东西: -------------------------------------------------------------------------------------------------------- 手机有吧。打开进入短信编辑状态,设置输入方式为英文,然后操作一个键单击、双击、长按,看屏幕输入有何变化。 但是你在打电话,输入电话号码的时候,此时只响应单击,和长按了。单击就是在释放后响应的。双击此时是两次单击。 -------------------------------------------------------------------------------------------------------- 应该先去证明一下,而后再发表意见。如果你的手机没有按键键盘,那么也应该找一个体会一下。 请不要说,因为手机的键盘是“实在是太不人性化”的“不是一个优秀的人机交互设计” ,所以IPHONE 取消了键盘,用手写了。现实中大量的电子设备和仪器,并没有屏幕、鼠标、手写的交互,就是简单的LED 灯和按键,所以多功能按键到处都有的。 看个最简单的例子,到商店找个电子手表,它就2-3个按键,你设置一下日期和时间,体会一下吧。至少你能发现一个按键有短按和长按连_发的功能。如果你认为它“实在是太不人性化”的“不是一个优秀的人机交互设计”,那么你如何设计?为电子表增加一个鼠标接口?================================================================================================================== 现在的系统,成本核算非常重要。你可以增加一个或几个键,使得“人机交互人性化”,单成本也是要增加的。对于有些不常用、特殊的功能,通常使用多功能按键完成,而常用,经常的操作,尽量简单,不用多功能的按键。这是综合平衡的办法。 东西是死的,人是活的。只要你有能力,就能设计出合理的交互方式。 还是讲手表上的一个键,如果是用户在查询时间方式工作,希望这个按键只有单击的单一功能,响应要快,而用户在设置时间方式工作,希望这个按键是多功能的,有单击和长按连_发的功能,但此时单击的响应要慢点了。 如何处理这个矛盾? 这个也简单呀。你写2套低层的驱动,一套就是扫描按键的按下,马上响应,另一套是需要等待的。然后增加一个状态判断,如果是上层在查询时间方式,那么使用前一套扫描按键,反映肯定快,如果上层在设置时间方式,就使用第2套扫描按键,此时单击响应要慢一点。这样不就平衡了吗?谁一天到晚去设置日期和时间? 还不是大状态机套小状态机吗? ================================================================================================================== 在我编写的教材中,已经说明状态机是系统分析的一种方法,不是我发明的。采用状态机的按键设计也不是我率先提出的。都是早就有的东西。我只是拿按键这个小的例子,引出状态机设计的方法,让大家去体会,并能掌握这个方法去使用在其它的地方,就是一个系统主工作方式,通常都是可以用状态机的思路来进行分析和设计,并实现的。回复举报 发表于 2011-8-26 08:49:23 |只看该作者35楼学习了
回复举报
ifree64 发表于 2011-8-26 08:54:21 |只看该作者36楼5501501
主题好友积分
金牌会员
莫元
1501发消息
ifree64
5501501
主题好友积分
金牌会员
莫元1501
发消息
packer
20542
主题好友积分
高级会员
莫元542
发消息
lexuezhitu 回复【33楼】machao 我在6楼已经给出了实际的东西: -------------------------------------------------------------------------------------------------------- 手机有吧。打开进入短信编辑状态,设置输入方式为英文,然后操作一个键单击、双击、长按,看屏幕输入有何变化。 但是你在打电话,输入电话号码的时候,此时只响应单击,和长按了。单击就是在释放后响应的。双击此时是两次单击。 -------------------------------------------------------------------------------------------------------- 应该先去证明一下,而后再发表意见。如果你的手机没有按键键盘,那么也应该找一个体会一下。 -----------------------------------------------------------------------状态机的思想我也是非常喜欢用的,并且很好用。昨天发帖子时因为网络故障,关于人机交互这方面我的意思表达得并不全面,我的意思不是说使用单击和双击就是差的人机交互,而是如果一个按键的功能单击和双击风马牛不相及,甚至逻辑矛盾,那么就是差的人机交互设计。比如单击用于删除、双击打开,那么在需要打开文件、或者删除文件时,就必然会发生一些单击、双击的错误操作。而像windows 的资源管理器那样对单击、双击的具有“逻辑延续性”的功能定义正正是需要认真学习的人机交互功能设计。刚才也特意试了下我手中的山寨手机在英文输入下的按键处理,可能这个手机功能实在太山寨了,没有长按和双击的支持,也许其他手机有这样的功能吧。不过,我也仔细想了一下手机如何利用非常少的按键实现众多功能的,貌似问题的关键不是单击、双击、长按。而是“确定”、“取消”两个按键在不同时候有不同功能,通过“确定”、“取消”、“上”、“下”这几个功能键构成了一个菜单系统。是不是这种方式才是更好的利用少量按键实现多种功能的方法呢(这里也用一个状态机来规定不同状态下同一按键的功能)?当然适当的定义长按和双击可以带来更加灵活的变化,不过我比较反对对同一个键的不同按的方式定义“逻辑不相关”的功能。比如“+”键,单击加一次,长按加十次,按着不放再连_发“+”的功能,应该就是一种非常“直白" 的功能定义,但如果把”+“键,单击定义为加,双击定义为减,恐怕就不是一个很好的功能第一。PS :我前面关于windows 对鼠标单击、双击的处理提到windows 的消息机制,这个是windows 系统很底层的驱动行为;不知为什么大家都用windows 资源管理器的行为来讨论windows 对鼠标单击、双击的处理。windows 的鼠标驱动和windows 资源管理器之间的关系正如马老师贴出来的按键驱动与上层应用之间的关系。回复举报 发表于 2011-8-26 09:15:15 |只看该作者37楼回复【33楼】machao W 鼠标双击一个文件,包括2个动作:1-选中该文件,2-打开文件,单击一个文件的动作是选中该文件。由于双击的第1个动作与单击相同,所以其双击操作的第1次单击不需要等待,可以马上响应的。 这个也简单呀。你写2套低层的驱动,一套就是扫描按键的按下,马上响应,另一套是需要等待的。然后增加一个状态判断,如果是上层在查询时间方式,那么使用前一套扫描按键,反映肯定快,如果上层在设置时间方式,就使用第2套扫描按键,此时单击响应要慢一点。这样不就平衡了吗?谁一天到晚去设置日期和时间? -----------------------------------------------------------------------请问马老师,如何用2套底层驱动切换的方式实现类似windows 资源管理器对鼠标单双击功能呢?我觉得这个问题的答案才是windows 鼠标驱动和您的方式在本质上的区别。回复举报 发表于 2011-8-26 09:18:02 |只看该作者38楼马老师这句话太对了“现在的系统,成本核算非常重要。”我经常被要求只给4个键,而要完成10种以上功能操作,我倒是想学explorer ,实在学不来回复举报 发表于 2011-8-26 09:22:53 |只看该作者39楼
学习了!
2
主题
新手上路0好友27积分
莫元
发消息27
回复
cjr82123 发表于 2011-8-26 10:01:33 |只看该作者
每次见马老师都有收获,谢谢马老师!
自从用了状态机后,腰也不疼了,腿也不酸了,走路也更有劲了。举报40楼
22
主题
中级会员0好友483积分
莫元
发消息480
回复举报
返回列表123456781 / 8 页下一页
高级模式
您需要登录后才可以回帖 登录 | 注册
发表回复 回帖后跳转到最后一页
阿莫电子论坛, 原" 中国电子开发网"
2004-2012 www.amobbs.com , 原www.ourdev.cn, 原www.ouravr.com 手机版|Archiver |阿莫电子论坛(原中国电子开发网) ( 粤ICP 备09047143号 )GMT+8, 2012-8-3 15:04 , Processed in 0.065857 second(s), 7 queries , Memcache On.