Q:
楼主书中的内容还有需要改进的地方,
1:如果将 Pn.x 口设置为开漏输出,则 Pn.x 绝对不会短路,
也就用不着将其它 Pn.x 设置为输入状态。
2:即使 Pn.x 只能设置为推挽输出,也不需要 Pn.x 输出高和低两个状态,
只需将当前 Pn.x 输出低状态就够了,其它的 Pn.x 则设置为输入,
此时 Pm.x 为低表示有按键按下,为高表示无按键。
3:加二极管来防止四点短路确实可行,但如果由于成本或硬件原因不适合加二极管,
那么还有软件的方法来对四点短路进行判断(电脑键盘就是这么做的),虽然不能避免
四点短路,但能发现四点短路,一般来说这足够了。
A:
1.你说的设置为开漏输出,我的理解是当前IO口为open drain结构,此时将IO口内部的上拉电阻关掉,不知我这样理解是不是和你的说法一致。如果相同,你的这种方法只是针对部分单片机有效,如果单片机IO是三态门结构,是没有内部上拉电阻进行选择的。另外我的主要目的是想让大家知道存在这样的风险,在实际应用中需要引起注意,我给出参考解决方法不代表这个方法是唯一可行之道,无论将其它IO口改成输入还是将内部上拉电阻关掉,都是通过设置避免不同IO在连通时出现一个输出高另外一个输出低的情况。
2.呵呵,是不是觉得我在文中要求输出高和低没有必要,好像是多此一举?这样做是有一定好处的,我在文中特意没有做相关说明,就是希望有你这样看过之后进行认真思考,并能提出自己的意见,这样才能加深技能技巧的印象。你这个问题质疑得好,为什么需要输出高和低两种状态,是为了避免其它错误,比如输入的IO口与地或者电源之间短路,只输出一种状态就可能做出错误的判断,假定Pm.0与地短路,是不是就会错误的判断成Pm.0上有键按下?
3.在文中已经说了二极管会增加成本,实际应用中可以通过软件方法判断多点按下将按键忽略
Q:
我说的开漏输出可以有上拉电阻,也可以没有上拉电阻。我认为用开漏输出扫描键盘是一种简便的方法,如果单片机有开漏输出功能的话,可以考虑采用。
输出高和低两种状态对判断Pm.x对地短路是有效果,不过我认为出货的产品一般都把硬件错误解决了。看来,用不用输出高和低两种电平,这没有绝对的答案,还是看自己的取舍了。
A:
看来我对你所说的开漏理解是相同的。在前面回复中已经明确说明,如果解决的方法有多种,不是说非要用某一种才可以,如果单片机支持你说的功能选择,一样可以解决问题。书中内容的目的是提醒大家需要注意有短路的可能,应该在程序中加以避免,实际上有的单片机的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的值,你想想没有保护是什么样的后果?再比如目的地址,被意外指向系统区域,也是不允许的。
allen_zhan_752827529 2014-4-24 15:40
1989tie_959541171 2013-8-21 12:02
allen_zhan_752827529 2013-8-19 17:57
我踌躇着不知道该如何回答您...如果是因为您对我们讲述的领域(freescale 的 kinetis L ,cortex-m0+)不熟悉, 只是就语法论语法, 那么您是对的, 我为自己的轻率发言表示歉意. 如果是上述专业方向, 见3楼4楼的讨论.
用户1454004 2013-8-19 15:18
allen_zhan_752827529 2013-8-15 17:41
另外, 我还想说一句啊, 老兄, 十年入门啊... 十年你都不能理解这个 register 的定义... 正好就是我说的 "初学者" 概念啊... 正好就是我在这篇 blog 中疾呼的, 不能随意模仿低阶的编程水平, 不能跟这个 sample 中的 coder 想当然的随手编程 |= 这样...老兄... 我们中国工程师不能落于世界平均水平之后啊...
allen_zhan_752827529 2013-8-15 17:39
用户1454004 2013-8-15 17:11
allen_zhan_752827529 2013-8-15 13:56
你说的很对, |= 与 = 意义是不同的. 其原因就是在 register 的定义中有体现, 你可以看看我其他一份文章里面有提. 对于很多 registers 来说, write0 代表意思不是 "disable", 不是"set 0", 而是"什么都不做, 什么都不影响". 也就是说, 不管是否原有 resigter 的某个 bit 是否为1, write 0 不会影响到这个bit, 也不会将原来为 1 的改变为0. -- 这就是我们说, 为什么此处 coder 犯了初学者错误的原因. |= 带来了代码尺寸的浪费, 效率的降低, "边缘效应"就不提, 我们也不知道可能会带来什么影响. 所以说起来, 为什么官方的 team 没有仔细研读官方的 datasheet 是好奇怪的事情. 但是这不关我们的事儿, 我们只要知道这个 |= 是一种彻底的浪费, 以及反应出编程的初学者痕迹即可.
用户1320373 2013-8-15 13:42
allen_zhan_752827529 2013-8-15 12:30