运行仿真电路时,按下独立按键K1~K5键可分别控制连接PC、PD端口的数码管显示开/关、加减与清零。通过学习与调试,要熟练掌握最基本的按键输入检测方法。案例电路及部分运行效果如图3-8所示。
图3-8 K1~K5控制两位数码管开关、加减或清零显示(含相关器件实物引脚)
(一)按键电路
按键实物一般如图3-8左下角所示,其4个引脚使之在实物电路板上的焊接及操作更加稳固,4个物理引脚以中间沟道为分界,同一边的两个引脚(假设为a1、a2)是内部互通的,另一边的两个引脚(假设为b1,b2)也是内部互通的。如果将a1、a2称为a端,b1,b2称为b端,可知其逻辑引脚如同仿真电路中的K1~K5按键一样各有两个引脚(a,b)。仿真电路中按键K1~K5一端接地(GND),另一端接PB端口的低5位(RB0~RB4),源程序将双向端口方向设为输入。按键的两种输入操作如下。
(1)按键按下时:RB0~RB4中的相应引脚将被接地,端口读取到低电平(输入为0)。
(2)按键未按下时:RB0~RB4中的相应输入引脚处于高阻状态(漏极开路,Open Drain)。
因此对K1~K4必须引入上拉电阻(Pullup Resistor),在按键未按下时,端口电平能够被拉高,程序能够读取到输入值1。由于PIC单片机PB端口可设置内部弱上拉(nRBPU=0),本例仿真电路通过启动内部弱上拉而省去了输入端口的外接上拉电阻。
(二)按键程序
源程序通过比较RB0~RB4引脚读取的值是否为0,对K1~K5分别给出了DOWN操作定义。程序运行时,每一按键操作都会立即被检测并执行,由于端口扫描检测速度很快,一次按键操作可能被快速多次检测到,从而导致某操作被反复执行。例如用户即使快速按下K3并释放,但数码上显示的数值却会一下子增加很多。
为使按键按下后无论是快速释放还是延时释放,都不会导致某项操作被重复执行,源程序定义了变量Recent_Key(初始时默认值为0xFF),以下分三种情况来说明它如何发挥作用。
(1)最初的无按键状态:程序读取的PORTB与变量Recent_Key的默认值均为0xFF,if语句判断二者相等,其后的continue语句使所有后续操作均被跳过。
(2)某按键按下:此时程序读取的PORTB与变量Recent_Key的值(0xFF)不再相等,因为读取的PORTB中出现了一个0。if语句判断二者不相等,else分支使Recent_Key保存当前端口值PORTB(相当于保存了当前所有按键的最近操作状态,该值不再是0xFF)。随后,当前按键对应的操作被处理(如开显示、关显示、递增或递减显示、清零)。当进入下一次循环时,如果该键还未及释放,此时程序读取的PORTB将与变量Recent_Key相等,if语句后面的continue使其下面的其他代码均被跳过,从而不会因按键未及释放而导致某项操作被重复执行。
(3)按键释放:该键释放后,程序读取的PORTB将为0xFF,此时PORTB与Recent_Key不相等(因为Recent_Key保存了此前的有键按下的状态),Recent_Key再次刷新了最近的PORTB的值(0xFF),在进入后面的按键处理程序后,由于PORTB为0xFF,与后续任一按键判断分支均不匹配,故不会执行任何操作。此时PORTB与Recent_Key相当于回到了(1)的状态。
① 将K1~K5改接在PORTB端口的高5位,重新修改程序实现同样的功能。
② 在4位集成式数码管显示电路中添加按键,用按键控制数码管数字显示开/关、增减及清0操作。
③ 修改主程序代码,在增、减按键未释放时,数字能按一定的速度实现连续递增与递减显示。