打印

《删繁就简-单片机入门到精通》之键盘扫描

[复制链接]
2897|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
sj_dai|  楼主 | 2010-2-24 11:16 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
看到有朋友咨询一个键盘扫描电路是否可以用的问题,这里将我写的键盘扫描应该注意的问题发出来。

勘误:
107页中间位置
...,可以正确判断出只有键7按下
修正为
...,可以正确判断出键7未按下

1
2
3

相关帖子

沙发
流行音乐| | 2010-2-24 18:20 | 只看该作者
楼主书中的内容还有需要改进的地方,
1:如果将 Pn.x 口设置为开漏输出,则 Pn.x 绝对不会短路,
   也就用不着将其它 Pn.x 设置为输入状态。
2:即使 Pn.x 只能设置为推挽输出,也不需要 Pn.x 输出高和低两个状态,
   只需将当前 Pn.x 输出低状态就够了,其它的 Pn.x 则设置为输入,
   此时 Pm.x 为低表示有按键按下,为高表示无按键。
3:加二极管来防止四点短路确实可行,但如果由于成本或硬件原因不适合加二极管,
   那么还有软件的方法来对四点短路进行判断(电脑键盘就是这么做的),虽然不能避免
   四点短路,但能发现四点短路,一般来说这足够了。

使用特权

评论回复
板凳
sj_dai|  楼主 | 2010-2-24 23:10 | 只看该作者
很高兴“流行音乐”提出中肯的意见,这里我对你的意见做一点解释。

1.你说的设置为开漏输出,我的理解是当前IO口为open drain结构,此时将IO口内部的上拉电阻关掉,不知我这样理解是不是和你的说法一致。如果相同,你的这种方法只是针对部分单片机有效,如果单片机IO是三态门结构,是没有内部上拉电阻进行选择的。另外我的主要目的是想让大家知道存在这样的风险,在实际应用中需要引起注意,我给出参考解决方法不代表这个方法是唯一可行之道,无论将其它IO口改成输入还是将内部上拉电阻关掉,都是通过设置避免不同IO在连通时出现一个输出高另外一个输出低的情况。

2.呵呵,是不是觉得我在文中要求输出高和低没有必要,好像是多此一举?这样做是有一定好处的,我在文中特意没有做相关说明,就是希望有你这样看过之后进行认真思考,并能提出自己的意见,这样才能加深技能技巧的印象。你这个问题质疑得好,为什么需要输出高和低两种状态,是为了避免其它错误,比如输入的IO口与地或者电源之间短路,只输出一种状态就可能做出错误的判断,假定Pm.0与地短路,是不是就会错误的判断成Pm.0上有键按下?

3.在文中已经说了二极管会增加成本,实际应用中可以通过软件方法判断多点按下将按键忽略。

再次感谢“流行音乐”的点评。

使用特权

评论回复
地板
流行音乐| | 2010-2-25 19:40 | 只看该作者
本帖最后由 流行音乐 于 2010-2-25 19:57 编辑

我说的开漏输出可以有上拉电阻,也可以没有上拉电阻。我认为用开漏输出扫描键盘是一种简便的方法,如果单片机有开漏输出功能的话,可以考虑采用。
输出高和低两种状态对判断Pm.x对地短路是有效果,不过我认为出货的产品一般都把硬件错误解决了。看来,用不用输出高和低两种电平,这没有绝对的答案,还是看自己的取舍了。

使用特权

评论回复
5
sj_dai|  楼主 | 2010-2-26 10:32 | 只看该作者
呵呵
看来我对你所说的开漏理解是相同的。在前面回复中已经明确说明,如果解决的方法有多种,不是说非要用某一种才可以,如果单片机支持你说的功能选择,一样可以解决问题。书中内容的目的是提醒大家需要注意有短路的可能,应该在程序中加以避免,实际上有的单片机的IO不支持输入输出选择,如果是这样的单片机那书中的内容就完全是错误的,对于这类细节,是需要读者自己去理解的。

这一点再多说两句,对于单片机内部的上下拉电阻,许多时候芯片资料对介绍并不清楚,这个电阻有多大,就是介绍也只是一个比较笼统的参考值,对于某些特殊电路,在外面另外加上下拉电阻的做**更稳妥,这样当出现多个电阻并联的情况时设计人员可以更精确的预估电阻值对电压的影响。我用一个极限例子来进行说明,有10条IO口都设为输入加内部下拉,这10条IO会同时读某一个信号量,但这个信号的电流驱动能力并不高,通常单片机内部下拉电阻为几十K,假设为47K,这样10条IO并联等效电阻就只有4.7K,这个电阻有可能把信号幅度拉低,比如是5V信号,4.7K电阻需要信号有1mA的驱动能力,如果其实际驱动能力值有0.5mA,会是什么样的后果?

做产品开发你所说的认为硬件把错误都解决了的想法不可取,合作是要相信别人,但绝对不能完全依赖别人,最好的做法是在条件允许的情况下,将自己的工作部分考虑更周详,更加稳定可靠。
还是你举个例子来说明你这种想法的问题所在,现在需要你写一个供别的同事实用的函数。
int data_copy(char *src,char *dec,int len)
按你的说法,只要在函数内部完成数据复制功能就可以。如果只是站在完成任务的角度,你这么做就已经可以,但绝对不能说你这样完成是高质量。
实际上如果有可能,应该在函数内部对参数做出一定保护,象int len,正常情况使用的同事会给出正确的值,但某些意外因素导致这个值被错误的设置或修改为小于0的值,你想想没有保护是什么样的后果?再比如目的地址,被意外指向系统区域,也是不允许的。

使用特权

评论回复
6
流行音乐| | 2010-2-26 21:10 | 只看该作者
明白。:)

使用特权

评论回复
7
eastcomchu| | 2010-3-18 21:14 | 只看该作者
恩,分析有道理。可以借鉴。

使用特权

评论回复
8
xlsbz| | 2010-6-22 19:27 | 只看该作者
牛!!

使用特权

评论回复
9
醉心369| | 2016-1-4 10:06 | 只看该作者
本帖最后由 醉心369 于 2016-1-4 10:07 编辑

楼主,买了你写的这本书,写的非常好,
有个问题想请教:
P106但这样改动后即便没有按键Pm.x也能读到1,……

从你的写的意思来看,Pn为输出,Pm为输入,平常没有按键按下,Pm读到的电平为低,当按键按下时电平为高。
(从P106第四段我看你的意思总结的,扫描键盘矩阵时Pn为输出口,……)
对于上个问题。我感觉是0啊,怎么即便没有按键Pm.x也能读到1呢,请帮忙分析分析

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

50

帖子

1

粉丝