拨码开关常用于编码设置或状态设置,普通开关与拨码开关应用电路图3-10所示,其中中还使用了8总线三态驱动器74LS245控制数码管显示。开显示时,拨码开关当前编码值被实时刷新显示在数码管上。本案例还演示了单刀双掷开关控制报警器声音输出的效果。
案例仿真电路中74LS245的CE引脚可以直接接GND的,但在图3-10中将其连接在P2.0引脚,用于动态控制74LS245的输出。主程序初始时将CE引脚值设为0,使能输出。在关显示时将CE引脚值设为1即关闭段码输出,以关闭显示。关闭显示还可以通过关闭段码或位码的方法实现。
图3-10 普通开关与拨码开关应用电路
由于4位数码管连接在P2端口的高四位,从左到右扫描时的位码应为0x10、0x20、0x40、0x80(即00010000,00100000,01000000,10000000),由于该4位数码管为共阴数码管,故其位码实际应为~0x10、~0x20、~0x40、~0x80(即11101111、11011111、10111111、01111111)。P2循环输出这4个位码即可实现扫描显示,对应语句为:
但由于最左边的第一个数码管在本例是不用显示的,故有:
由于拨码开关连接在P0,主程序直接读取P0的值即可获得拨码开关编码值,并将其分解为3个数位放入disp_buff,即可逐一发送数码管显示。
运行测试程序时本应出现正确结果,实际却出现显示异常。这是因为控制位码的语句P2=~(0x20 << i)使P2.0引脚值恒为1,为了开显示,CE引脚值原本被置0,即P2.0引脚值为0,该语句却使其又被置1。为解决这一问题,P2端口的输出位码需要和0xF0执行与操作,修改后的数码管动态扫描显示程序中的位码输出语句如下。
对于报警声音输出的程序设计,其关键在于Alarm函数,其中BUZZER=~BUZZER语句向P3.3引脚持续输出1010101010…序列,形成的脉冲信号使扬声器输出声音,如果BUZZER=~BUZZER语句的执行间隔相等,系统会发出单调的声音,不会模拟出报警效果。在Alarm函数内的双重for循环中,内层for循环由参数t控制,不同的t值使BUZZER输出具有可变的延时间隔,从而形成可变频率,模拟出报警声音的效果。当SW2合上时,Alarm(20)与Alarm(40)输出了两种不同频率的声音,模拟出很逼真的报警效果。
① 修改程序,使拨码开关编码显示在数码管左3位上。
② 去掉74LS245驱动器,仍实现数码管的显示开关功能。
③ 调整程序中报警函数Alarm的参数值20与40,所听到的声音效果有何变化?使用虚拟示波器能够观察到什么样的输出波形?