h( _( T+ z# ?' h K$ w扫键流程:先检测3个行IO口,对K1’,K2’,K3’进行扫键,之后如上述2*3扫键流程。5个IO口能扫9个键,够厉害吧,足足比6个键多了1/2!' T$ h* ^* P8 k# C. x* h
动动脑,还能不能再多扫几个?就几个?一个也行!好,再想一下,硬是被逼出来了!如图三:+ `+ l; e% q0 N @+ `9 `) Z7 R8 g + F8 L3 r# H9 [, l* Y# b
! }- I% N$ }( r6 F6 e ( {' L& P0 i+ o7 V3 ~不多不少,正好10个键!这种扫键方式比较少见吧!漂亮!扫键流程:设IO1输出为“0”,检测IO2…IO5,若判断有相应健按下,则可知有健;若无键,则继续扫键:设IO2输出为“0”,检测IO3,IO4,IO5,判断有无键按下,如此类推。这里应注意:当扫某一IO口(输出为“0”)时,不要去检测已经扫过的IO口。如:此时设置IO2输出为“0”,依次检测IO3,IO4,IO5,但不要去检测IO1,否则会出错(为什么,请思考)。( ?/ S4 ]9 @9 F8 i# m5 `/ o8 U
感觉怎么样?不错吧!让我们再看看图三,好有成就感!看着,看着……又看到了什么?快!见图四:, D6 c! K: r( o7 m5 c3 q" O* o, D9 e % U0 C1 T9 g8 C6 q q. i `% I / K3 a) p _. M$ j; j- }+ s9 a真强!被您看出20个键!多了一个对称的三角形。可是,像这样的排列能正确扫20个键吗?回答是肯定的:不能!上下三角形相互对称,其对称扫出的键无法区别。有没有注意到分析图三时提到的注意点?(à“当扫某IO口时,不要去检测已经扫过的IO口,否则会出错”)- A3 Z, p; W; r* w9 \5 L+ w
我们分析一下图四:当IO1输出“0”时,按下K11或K11’键都能被IO2检测到,但IO2检测却无法区别K11和K11’键!同理,不管扫哪个IO口,都有两个对称的键不能区分。" C: \8 |: i: G! x( U3 U$ u
我们假想,如果能把对称键区分开来,我们就能正常地去判断按键。我们在思考:有没有单向导通性器件?有!见图五! 6 ^- D5 v/ x% _! ?2 n4 K' z0 |5 }
- D: `/ e: E3 I2 O% G; q2 i/ J- e7 W- i6 O3 C3 e% T) m# X' l
A6 I! c9 A M) u" V5 z
很巧妙的思路!利用二极管的单向导通性,区别两个对称键。扫键思路:对逐个IO口扫键,其他四个IO口可以分别检测其所在的四个按键。这样,就不会有分析图三时提到的注意点。 ! f( E D) S- ^. j- D! i+ z* n够酷吧!等等,大家先别满足现状,我们再看一下图二,是不是有点启发?对,我们再分析一下“用5个IO口对地衍生的5个键”。看图六:& a$ S/ D& I6 p4 S3 t/ s 0 F1 p8 C9 S$ N6 H$ L
( N+ R- |7 Q$ f. e$ W2 g; [! D. _, w
25个键!5个IO口扫出25个键!先别激动,我们再分析一下它的可行性,分析通得过才能真正使用。假设扫键流程:先扫对地的5个键,再如图五扫键。先扫对地5个键,判断没有按键,接着对逐一对IO口进行扫键。但当对某一IO口扫键时,如果有对地的键按下,这时有可能会误判按键,因为对地键比其他键有更高的响应优先级。例如:扫IO1,IO1输出“0”,恰好此时K62按下,IO2检测到有按键,那就不能判断是K11还是K62。我们可以在程序上避免这种按键误判:若IO2检测到有按键,那下一步就去判断是否有对地键按下,如果没有,那就可以正确地判断是K11了。. Y/ x' V w F$ F
我们小结扫键个数S:! e! z7 l9 n* q f9 e
S = (N-1)*N + N ――启用二极管4 a, f/ M9 J& L+ s2 r
S = (N-1)*N /2 + N ――省掉二极管