集成式数码管显示一般采用动态扫描刷新显示方法,即在发送段码与位码完成一位数码显示后,调用延时函数delay_ms,在短暂延时后显示下一位数码,如此循环快速扫描,实现刷新显示。在图3-19所示电路中,改用了新的动态扫描刷新显示方法,数码管刷新程序由定时器溢出中断控制,同样实现了集成式数码管的动态显示。为实现更丰富的演示功能,仿真电路中对两组数据(年、月、日,时、分、秒)实现了切换显示。
图3-19 T1控制数码管动态显示电路
本案例使用STC15的T1,工作于11.059 2MHz时钟频率下,通过4ms定时中断,驱动数码管动态扫描以刷新显示。编程时可通过STC-ISP工具生成初始化代码,所生成的初始化代码中,AUXR &=0xBF(即10111111)将AUXR寄存器的第6位T1x12置1,表示T1选择计数驱动时钟为12分频;TMOD &=0x0F(00001111)将TMOD的高4位全部置0,其中高4位的后两位00将T1配置为模式0。
下面再来分析一下应如何设置T1定时/计数初值。在STC-ISP工具所生成的代码中,定时/计数初值为0xF19A,这是如何得到的呢?
本案例系统时钟频率为11.059 2MHz,由于配置为12分频(与传统8051单片机的默认分频值相同),故计数驱动时钟为11.059 2MHz/12=0.921 6MHz(小于上一个案例中的1MHz计数驱动时钟)。也就是说,其计数时钟周期 T cy =1/(11.059 2MHz/12)≈1.0851≈s,即每1.08510s将计数值累加1。
为实现4 000 s定时(计数),可设置定时/计数初值为65 536-4 000/1.0851≈65 536-4 000×(11.059 2MHz/12)≈65 536-3 686=61 850=0xF19A。可见,在0xF19A(61 850)基础上,经过3 686次累加将达65 536,使T1产生溢出,也就是经过3 683×1.08516s≈4 0000s后溢出,触发T1中断。
通过上述分析,对于源程序中的对应语句就很好理解了:
对于1T(1分频)模式下的定时/计数初值计算,可参考本案例程序,这里不再赘述。
用T1控制集成式数码管刷新显示,定时/计数初值的设置很重要。该初值设置得不好将导致数码管显示闪烁、亮度不足或字符滚动。本案例8个数码管每隔4ms切换显示下一个字符。由于视觉惰性,其快速切换使人不会察觉到它们是逐个出现并在4ms后消失,而会感到所有字符是同时稳定地显示在数码管上。
设置好定时/计数初值以后,使TR0 T 1即可启动T0,T0将在4ms后溢出。由于IE=0x88许可了T1中断,T1中断函数将被调用,完成对一位数码管的刷新显示,如此不断以4ms间隔触发T1中断,即可实现整个集成式数码管每一个数位的动态扫描刷新显示。
T1中断函数内控制的变量i与j分别是二维数组Table_OF_Digits的行与列索引。T1中断每隔4ms被触发,数组第i行第j列字符被显示,同时j递增,4ms后T1中断再次被触发,下一字符被显示,依次下去,第i行的8个字符被反复刷新显示在8只数码管上。
二维数组中一行8个字符的持续刷新显示时间由变量t控制。增加t值会延长一行字符显示在数码管上的时间。程序中的t为350,要注意将t定义为u16类型。在一行8个字符显示一段时间后,i的增加会使数码管更新显示出下一行字符。
细心研究时会发现,每一趟刷新要显示8个字符,如果t为350时开始切换到下一行,由于350/8=43余6,这表示t增加到350时,数码管刚刚完成第43趟刷新,开始进入第44趟第6个字符的刷新,在第44趟8个字符中还剩2个字符未被刷新显示时,变化i值而切换到另一行,这样会不会出现显示错误呢?
实测结果是,不管所取的t值是否能整除8,显示结果都是正常的。例如,当t为350时,将t清零,数码管上前6个字符仍是数组当前行的,i值变更后,后续显示的将是新行的第7和第8个字符,这时数码管上前6个字符是一行,后2个字符是另一行,这样显然会出现两行混合显示的情况。但由于每个字符仅停留4ms即被刷新,前面6个异常的字符会在极短的时间内,即在第45趟(或称为新开始的第0趟)被刷新为新行的前6个字符,因此用户是根本看不到这种混合显示的现象的。
如果希望切换新行时不出现可能的瞬间混合显示现象,要么将t值取为可被8整除,或者直接在变更i值的同时将j值归0,这样可保证输出新的一组数据时,输出的起始位码为P2=~(1<<j)=~(1<<0)=~0x01=0xFE。
除了可以使用T1中断函数实现数码管刷新显示以外,还可以不启用T1中断,并删除T1中断函数,然后在主程序while循环语句内通过查询T1溢出标志位TF1(TIMER1 Overflow Flag)是否被置位来判断是否出现定时/计数溢出,TF1为1时表示定时4ms已到达,此时将TF1清零即可刷新数码管显示。定时/计数初值的重新装载在模式0下是自动完成的,与TH1、TL1对应的是隐藏的同地址重装载寄存器RL_TH1、RL_TL1。
① 修改程序,改用非反相驱动器7407驱动数码管显示。
② 重新设计程序,配置T0工作于1T(1分频)模式0控制3组以上数据自动循环显示。
③ 在仿真电路中添加按键,每次按下按键时切换显示下一组数据。