4842|6

7815

帖子

57

TA的资源

裸片初长成(中级)

楼主
 

底层读键 的 两种简单思路 的 空间 时间 开销 简单测试 [复制链接]

任何key,最基础的抽象,都是把键值抽象到内存上,由于按键的特殊性,它可以只需要用 位 来存储硬件上的键值状态。

一个需要关心的问题是 位是否足够表达足够多的键
任何一个系统,32位变量不在话下,即使8位机如51,long 或者 long long也可以是32位,甚至64位。
当然有些系统可能会有更多的按键,甚至多达百来个以上,这里先不考虑这种情形,何况在FreeUI里其实我只需要16个,大多数情况,二三十个就绰绰有余。

接下来是实现 最基本的 按键扫描。

  1. static int keybit = 0;// 其实 测试还应该包括 long int long long的区别对待

  2. #define MAX_KEY_BIT 32

  3. void size_of_keybit(void)
  4. {
  5.     static size_t size;
  6.    
  7.     size = sizeof(keybit);
  8. }

  9. //公平起见,操作都是全部写1
  10. void scan_key(void)
  11. {
  12.           int i;
  13.           keybit = 1;
  14.    
  15.          for(i = 1;i < MAX_KEY_BIT;i++)
  16.          {     //keybit |= 1<<i;
  17.              keybit <<= 1;
  18.              keybit += 1;    // 这个速度更慢,比第一种方法要慢33%左右
  19.          }
  20. }
复制代码

作为对比,考虑一下 以往的方法:

  1. static char keyvalue[MAX_KEY_BIT];

  2. void scan_key2(void)
  3. {
  4.     int i;
  5.    
  6.     for(i = 0;i < MAX_KEY_BIT;i++)
  7.         keyvalue[i] = 1;   
  8. }
复制代码




此帖出自编程基础论坛

最新回复

谢谢楼主的分享,内容特别特别好,学习到了。  详情 回复 发表于 2016-4-27 14:16
点赞 关注(3)
个人签名

强者为尊,弱者,死无葬身之地

 

回复
举报

7815

帖子

57

TA的资源

裸片初长成(中级)

沙发
 
结果:

我是在 stm32f030r8t6 下测试的,用的IAR。

编译后通过查看反汇编代码。

得出的结论是(当时我是用long long定义 keybit,所以实际是64位,当然 keyvalue数组也是64元)

key_scan() 生成的代码长度 是 38个指令
key_scan2() 生成的代码长度是 93个指令

两者之比 约为 2.58

但与想象的有点出入的是。

两者的运行时间 却是 2:1,后来猜测,这可能和每次都执行了一个 移位 和 一个 位或操作有关。
看来,和这个相比,取数组的偏移计算,在底层反而是微不足道的。

后来,改成32位后,时间差别还是 为 3:2.

所以结论是:

使用位的方式,节省存储器,数据和程序 存储空间 都节省。
但是时间上,却要慢一半到一倍。

这种时候,到底是牺牲时间换取空间 还是相反 完全取决于你。

毕竟在大多数情况下(仅仅只有二三十个键的话),空间和时间上都省不了太多东西。
此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

7815

帖子

57

TA的资源

裸片初长成(中级)

板凳
 
注:
我时间的测试方法是:

使用逻辑分析仪(当然也可以是示波器)。
然后把一个IO 写高写低,把这个操作插在要测试的函数调用前后,即可。
此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

7815

帖子

57

TA的资源

裸片初长成(中级)

4
 
最后扯一点:

其实这种测试 和 对按键 的抽象方式 都有点过细。
我现在也很少再纠结这么底层的封装问题了。

我之所以这么干,一个是为了实际测试运行时间的差别。

另一个就是,按键看起来简单,其实玩起来大有可为。
然而,许多时候,不管按键多复杂——
比如说连按啊,长短按啊,是松了再触发还是 按下就触发啊,其实这些都可以 放后处理,而嵌入式/单片机程序,最麻烦的地方,无非是 与硬件有关,所以,我就直接用 一小片内存,把硬件上的键值映射过来了。

这个地方,只要随便一个定时器中断或者循环体里,循环调用 这个 扫描函数,就能得到键值。
此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

7815

帖子

57

TA的资源

裸片初长成(中级)

5
 
另外啰嗦一点就是:

大多数时候按键需要计次消抖。
所以,用位还是有点麻烦,最终还是要用一个数组来计次。

如此说来,就等于回到了我平素的写法了,合二为一。

突然想知道你们是怎么写读键程序的——因为我最近在移植一个其他项目的UI,突然发现别人的想法和我的想法居然可以相差这么远,一开始我是有点抵触的,只是因为限于时间不得不硬着头皮,但后来随着半改半移植,也渐渐理解和接受了这种写法。
此帖出自编程基础论坛
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

578

帖子

0

TA的资源

纯净的硅(初级)

6
 
我读取键值是给每个按键用一个变量代表键值,使用定时器设置一个扫描标志位,每隔一段时间置标志位,然后在主程序中的while大循环中不断判断标志位,然后去更新键值,以供之后的程序使用。
此帖出自编程基础论坛
 
个人签名刻苦学习,共同进步
 
 

回复

18

帖子

0

TA的资源

一粒金砂(初级)

7
 
谢谢楼主的分享,内容特别特别好,学习到了。
此帖出自编程基础论坛
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表