分类:
2006-12-14 21:40:54
——欺骗眼睛的小伎俩——
大家一定还对微机实验中的四位数码管动态扫描显示的方法记忆犹新,因为我们的眼睛曾经心甘情愿地被这个小伎俩欺骗而乐在其中。
动态扫描显示的原理很简单,也很有意思。由于在实验中,片选信号和笔画码都是不经过数据锁存而直接由IO口送数码管的,并且四位数码管共用并行的笔画码数据线,因此,必须轮流选中某一位数码管,才能使各位数码管能显示不同的数字或符号。再利用人眼睛天生的弱点,对50Hz以上的光的闪烁不敏感,因此,只要轮流选中某一位的时间间隔不超过20ms(对四位数码管来说,相邻位选中间隔不超过5ms),我们就感觉数码管是在持续发光显示一样。
当然,如果为四位数码管设置独立的笔画码输出口/线,则需要较大的硬件消耗,而且使得硬件电路比较繁杂。当时深感动态扫描方法的奇妙。
——动态扫描局限性的思考——
硬件上的节省势必是由软件上的开销来平衡的。虽然这种动态扫描的算法非常简单,对于程序的编制几乎没有影响。但是,在实际的系统中与其它外设配合作为辅助的显示功能使用时,却显示出其应用上的局限性。
例如最近写了个模数转换的小程序。使用8位串行A/D TLC549,程序功能是将电位器的输出端电压送TLC549转换为数字量,并在四位数码管显示出电压值。
为了保证转换和转换结果显示的实时性,即改变电位器电压时,显示也立即随着改变为相应的数值,必须不断地启动TLC549进行A/D转换,这样就要不断地更新转换结果进一步不断地更新要显示的笔画码,这必须放到一个循环体中进行,记作循环A(A/D&数据处理循环)。但是为了保证动态扫描显示数码管,又必须不断地轮流选中数码管,并在选中的同时送出相应的笔画码,这也要在一个循环体中进行,记作循环B(片选循环)。
为了显示正确的数值,必须在更新了转换结果及其笔画码之后,才可送动态扫描显示(即转换一次,动态扫描一次)。这样得到下面的程序框架:
while( 1 ) {
①A/D转换;
②处理转换结果并得到相应笔画码;
for ( count = 4; count >0; count -- ) {
③选中某位并送相应笔画码;
④delay(片选时长);
}
}
这种把实现两种功能的代码放到一个循环体中的办法势必会使得两者的工作受到相互影响。
例如,在没有①②处理的纯粹的动态扫描显示的循环体中,选中某一片的时间间隔是4倍的delay(片选时长)[ ④这段延迟实际上是持续选中某一位的时间](严格地说还要加上③的时间),而将A/D转换以及结果处理加入进来之后,选中某一片的时间间隔就要在上面的时间再加上①②处理所需的时间。这样就降低了动态扫描的频率,如果①②的时间比较长,则可能导致数码管显示出现闪烁。
另一方面,轮流片选的for循环又使得A/D转换的时间间隔变长,在一些高速数据采集系统或高实时性控制系统中,势必影响了数据采集的速度和实时性能。
因此,动态扫描显示根本的局限性源于要占用一个while( 1 )循环体,而while( 1 )循环又必然是主程序的主循环体;这一弊端使得完全用软件来实现动态扫描的显示方法在实际应用中的价值大打折扣。
——用硬件来弥补软件缺陷——
上面所用的四位数码管由于共用一组笔画码数据线,因此只能使用分时的办法来传送笔画码来达到各位显示不同数值的目的。
根据实际情况,我们可以选用四片一位显示的数码管,即各位有各自独立的笔画码数据线,处理器将笔画码通过沿触发的D型数据锁存器来送到各位数码管,锁存器的触发时钟接地址信号(相当于片选)。例如74LS248就是一个显示BCD码的单位数码管。这样,一个简单的数据采集和A/D转换并显示处理结果的程序框架就变为:
while( 1 ) {
①A/D转换;
②处理转换结果并得到相应笔画码;
③往某片数码管(依I/O地址定)送相应笔画码;
}
若要进一步简化A/D转换结果到笔画码的转换,还可选用其他一些集成芯片,比如ICL7106/7107就是集成的单片三位半A/D转换电路,可以将A/D转换结果经内部译码电路转换为可直接送数码管显示的笔画码。