集成式数码管一般采用动态扫描法刷新显示,在发送段码与位码,完成一位数字显示后,调用__delay_ms,在短暂延时后显示下一位数字,如此不停地快速刷新显示,用户将感觉不到数码管的任何显示抖动或闪烁,而会觉得所有数位是同时呈现在数码管上的。图3-18所示的仿真电路仍采用动态扫描法,但其延时与刷新改用TIMER0溢出中断控制实现。
图3-18 TIMER0控制数码管扫描显示(含7406引脚)
(一)驱动电路设计
仿真电路中使用了反向驱动器(Invert Drive)7406,可用于指示灯驱动、继电器驱动等。本例用两片7406驱动数码管显示,每片7406可驱动6位数码管显示,其中第2片7406的6个驱动通道仅使用了2个,其余4个通道未使用。
(二)定时器溢出中断控制数码管刷新显示程序设计
通过定时器溢出中断控制数码管扫描显示的源程序结构与3.14节“TIMER0控制单只LED闪烁”的源程序结构非常相似,包括相关寄存器的设置与中断函数的编写,仅有的差别是前者仅在中断函数内控制LED闪烁,而本例则需要控制“段码”与“位码”输出,实现8位数码管的刷新显示。这里略去对程序结构的讨论。
另外,由于中断函数内所显示的是两组数据,中断函数用变量i,j标识二维数组Table_OF_Digits的行/列索引,TIMER0定时器中断每隔4ms触发,数组第i行j列字符被显示,同时j递增,4ms后中断再次触发时,下一字符被显示,依此下去,第i行的8个字符会被反复循环刷新显示在8位数码管上。
二维数组中一行8个字符的持续刷新显示时间由变量Keep_Time控制,时间近似等于Keep_Time×4ms,增加Keep_Time值会延长一行字符保持显示在数码管上的时间长度。中断函数内Keep_Time取值为260,要注意将t定义为INT16U类型。在一行8个字符保持显示若干时间后,i的增加会使数码管显示出下一行字符。
(三)未除尽不影响正常显示的原因分析
大家可能会发现:每一次刷新需要显示8个字符,在Keep_Time值为260时开始切换到下一行,由于33×8=264,Keep_Time增加到260时,刚刚显示完的是第33次的第4个字符,在第33次还剩4个字符未显示时,变化i值而切换到另一行,这样会不会出现显示错误呢?
实际结果是不管Keep_Time的上限是否能整除8,显示结果都是正常的。在t=260时,t归零,数码管上前4个字符仍是数组当前行的,i值变更后,后续显示的将是新行的后4个字符,这时数码管上前4个字符是一行的,后4个字符是另一行的,这样显然会出现两行混合出现的情况,但由于每个字符仅停留4ms即被刷新,前面4个异常的字符会在极短的时间内在第34次(或称为新开始的第0次)被刷新为新行的前4个字符,因此根本看不到这种混合出现的情况。
如果要求切换显示新行时不出现可能的瞬间混合显示现象,可将Keep_Time上限取为可与8除尽,或者直接在变更i值后,再添加语句j=0,这会使得任何时候切换到新行时,数据都从新行第0个元素开始重新刷新显示。
① 在本章例3.7的电路中用定时器控制数码管扫描显示。
② 设计程序控制三组数据的切换显示。
③ 重新编写程序,使每组数据能从左向右滚动进入显示屏,保持刷新显示一段时间后再切换显示下一组数据。