3.14 TIMER0控制数码管动态管显示 |
|
集成式数码管显示一般采用动态扫描刷新显示方法,在发送段码与位码完成一位数码显示后,调用延时函数delay_ms,在短暂延时后显示下一位数码,如此循环快速扫描,实现刷新显示。图3-17所示仿真电路中改用了新的动态显示方法,数码管刷新程序由定时器溢出中断进行控制,同样实现了集成式数码管的动态显示。为实现更丰富的演示功能,仿真电路中对两组数据(年、月、日,时、分、秒)实现了切换显示。
图3-17 TIMER0控制数码管动态管显示电路
(1)TIMER0的模式1配置及初值计算
本例主程序将使用TIMER0的模式1来实现4ms定时,不同于上一案例的是本例设TMOD= 0x01,使TIMER0工作于模式1,它与模式0的唯一差别是其最大计数位为16位,TH0与TL0均分别保存定时器初值的高8位与低8位。当定时/计数寄存器累加到65 535时,再次递增即产生计数溢出,对于所选择的12MHz振荡器,可用下面的两行语句实现4ms(4 000µs)定时:
设置初值的语句还可写成:
这是因为65 536即17位二进制数10000000000000000,其最高位为1,其余16位为0,对于16位的寄存器,65 536与0是相等的。为检验这一结果,可打开Windows附件中的计算器,计算65 536-4 000,得到61 536,然后单击“查看”/“科学型”/“十六进制”菜单,可得十六进制数F060,即TH0 = 0xF0,TL0=0x60;如果输入0-4 000,可得结果为-4 000,然后切换到十六进制,可得FFFFFFFFFFFFF060,显然,该结果的最后4位仍为F060,所得结果中将仅有最低4位被分别保存到TH0与TL0中。
定时器初值选择很重要,设置不当时会导致数码管显示闪烁、亮度不足或字符滚动。本例8只数码管每隔4ms切换显示下一字符,由于视觉惰性,其快速切换使人不会感觉到它们是逐个出现并在4ms后消失,而会感到所有字符是同时稳定地显示在数码管上。
(2)TIMER0的溢出中断函数设计
设置好定时器初值以后,置TR0 = 1即可启动TIMER0,TIMER0将在4ms后溢出,由于IE = 0x82许可了TIMER0溢出中断,中断函数将被调用,完成对一位数码管的刷新显示,如此不断以4ms间隔触发中断,即可实现整个集成式数码管每一数位的动态扫描刷新显示。
中断函数内控制的变量i,j分别是二维数组Table_OF_Digits的行与列索引,定时器中断每隔4ms被触发,数组第i行j列字符被显示,同时j递增,4ms后中断再次触发,下一字符被显示,依此下去,第i行的8个字符反复刷新显示在8只数码管上。
二维数组中一行8个字符的持续刷新显示时间由变量t控制,时间近似等于t×4ms,增加t值会延长一行字符保持显示在数码管上的时间长度。源程序中的t取值为350,要注意将t定义为INT16U类型。在一行8个字符保持显示若干时间后,i的增加会使数码管显示出下一行字符。
细心研究时会发现,每一趟刷新需要显示8个字符,在t值为350时开始切换到下一行,由于43×8=344,t增加到350时,刚刚显示完的是第44趟第6个字符,在第44趟还剩2个字符未显示时,变化i值而切换到另一行,这样会不会出现显示错误呢?
实际结果是,不管t的上限是否能整除8,显示结果都是正常的。如t=350时,t归0,数码管上前6个字符仍是数组当前行的,i值变更后,后续显示的将是新行的第7,8个字符,这时数码管上前6个字符是一行,后2个字符是另一行,这样显然会出现两行混合出现的情况。但由于每个字符仅停留4ms即被刷新,前面6个异常的字符会在极短的时间内在第45趟(或称为新开始的第0趟)被刷新为新行的前6个字符,因此根本看不到这种混合出现的现象。
如果希望切换新行不出现可能的瞬间混合显示现象,要么将t的上限取为可被8除尽,或者直接在变更i值的同时将j值归0,这样可保证输出新的一组数据时,输出的起始位码为P2 = ~(1<<j)=~(1<<0)=~0x01=0xFE。
(3)不使用TIMER0溢出中断函数实现数码管刷新
除了可以使用定时器溢出中断函数实现数码管刷新显示以外,还可以不启用TIMER0溢出中断,并删除溢出中断函数。在主程序while循环内通过查询TIMER0溢出标志位TF0(TIMER0 Overflow Flag)是否置位(TF0是否为1)来判断是否计数溢出,为1时表示定时4ms已经到达,此时将TF0软件清零,并重装定时寄存器,然后刷新数码管显示。
① 数码管位码驱动使用了反向驱动器7406,如果改为非反向驱动器7407,应如何修改程序?
② 重新设计程序,实现三组以上数据的自动循环切换显示。
③ 在仿真电路中添加按键,每次按键时切换显示下一组数据。