数码管动态扫描几乎是所有单片机入门书籍必写的章节了,程序其实很简单,10句以内就可解决(C51)。似乎是太简单太基础了,几乎所有的例程都没不曾提到:在一个大型的、运行时间较长的程序里实现效果如何?
其实在做那个温控器的时候就已经碰到这个问题,那次也是第一次用数码管动态扫描技术,以前都是用液晶显示器的,无论是段式的还是点阵式的,这个问题就是:数码管显示的时候各位显示亮度不完全一样,总是最高位显示的亮度最高,其他几位较暗,但是亮度比较一致,这个问题困扰了我一段时间,后来实际用的时候把最高位显示给屏蔽了(确实也用不到这一位,但是扫描还是要扫到的),所有这个问题算是忽略过去了。但是此次做调频收音机时又一次碰到了。程序流程大致如下:共有两个模块用到数码管显示,一个是显示调频频率,另一个是显示当前音量值,由音量控制按钮来控制这两个模块的轮流调用,实际调试时发现:轮到音量显示的时候,两位数字亮度是均匀的,而当由频率显示的时候,最高位数字亮度最高,其他位要暗一半以上,无论是在程序中多处安插扫描程序或者改变位扫描间隔都不能改变这一情况。经过两个模块的比较,发现了这两段程序的重大不同点,频率显示模块实际是先从tea5767中读出PLL数据,然后经过PLL到频率的运算,再经过二进制到BCD转换,最后送显示缓冲,期间用到了大量的乘除、浮点运算,众所周知51单片机的浮点运算能力是很差的,这个从加载浮点运算后程序所占空间大幅度增加就可以看出来,也就是说,此处的频率运算时间是很长的,而音量显示模块只是从ram中取了1字节做了一下二进制到BCD的转换,显然速度要快的多。说到这里,其实就很明白了,最高位显示更亮的原因就是由扫描程序运行间隔过长造成的!这是由动态扫描程序缺陷引起的,因为这种扫描程序没有锁存的功能,程序需要不停的扫描,才能保证显示效果,看这段典型的程序: uchar shift ;
uchar count=0 ;
uchar k;
shift=0xfe;
P2=0xff ;
for(k=0; k<8; k++)
{
P0=dis_code[dis_buf[k]];
P2=shift;
shift=_crol_(shift,1); //左移一位,选中更高的数码管
delayms(1);
} 可以看到,每次调用这段扫描程序后,数码管的位选线就停在了最高位,如果两次调用的间隔过长,就会造成最高位停留时间比其他位更多,而显示亮度恰巧与位选停留的时间长短有关! 解决方法非常简单,在位选循环结束后加了P2=0xff;关闭了所有数码管的显示,保证各位数码管的显示时间均等。经实验证明,这个方法是对的! 之所以没人提到这个问题(也许真是我看的书太少,没发现其实人家也是这么解决的??),我想现在大家做东西的时候大都是首选液晶显示器(价格也不贵,20来块钱,消费的起),或者使用的专用的显示芯片(程序无须时时扫描数码管),即使是为了节约成本,也使用了数码管动态扫描,也是因为主要用在了诸如“闹钟”等没有多少数学运算的项目上了。
|