当时在调一个液晶控制板,板子是新做的,自己动手焊接(水平有限,给后来的故事埋下了伏笔)。一切OK,就把早就写好仿真过的代码烧进去,然后接口部分是一个51的单片机,同样烧进备好的代码。本来就是先做一个很简单的指令测试,控制板部分是一个CPLD,一方面做MCU接口,接收指令(各种传送数据方式)和数据(缓存到RAM中);另一方面事实扫描LCD显示驱动。奇怪的是测试一条写数据指令,让LCD现实上半屏幕全红色下半屏幕全白色。指令控制方面MCU先是使用了内部的一个清屏指令,将LCD全清白色,然后使用一条写入一个数据后X坐标自增,如下做了一个简单的遍历处理。
for(m=0;m<136;m++) //上半屏幕显示红色
{
WR_XLADDR = 0;
WR_XHADDR = 0;
WR_YLADDR = m%256;
WR_YHADDR = 0;
for(n=0;n<480;n++)
WR_DATA = 0xe0; //单点红色}
}
而结果比较怪异,背景白色都没有问题,而上半屏幕的全红色却是第1行红色,第2、3行白色、第4、5行红色,第6、7行白色……如此下去。再测了一下Y自增方式,问题也类似,本来是要写左半屏幕绿色,右半屏幕黑色(也是先清屏黑色,再写绿色),出现了第1列红色,第2、3列白色、第4、5列红色,第6、7列白色……。他们都有共性,所以一直很纳闷,开始的时候总以为是出在CPLD代码部分,因为这次的缓冲SDRAM的控制是新设计,可能是这个控制时序的问题,再回头仿真测试结果没有改观。最后静下心来好好分析了下,而且特别在每次写入红色数据时加了很大的延时进行观察,发现第1行显示完红色立即跳到第4行显示红色,然后停了大约2行的时间再进行第3行的显示,紧接着是第6行的显示。于是就想到是不是最低两个地址线出现短路或者其中一个短路到GND或者VCC。而出现的地址是先2’b00,紧接着2’b11,先得很乖,如果是其中一个接GND了,那么地址出现顺序应该是00,00,10,10或者00,01,00,01;如果是一个接VCC了,那么地址顺序应该是01,01,11,11或者10,11,10,11。所以排除了地址脚和VCC或者GND短路的可能。还有就是,即便是地址短路了,如果出现在SDRAM的地址脚上,那么读写都一样,即所谓的负负得正,也不会出现这样的现象。
那么到底是出现了什么问题了呢?冒失每次遍历都会进行一次Y地址的重新写入(通过MCU与CPLD的接口),而清屏指令只要发一条指令,CPLD内部处理地址的运算。所以问题被定位到了MCU与CPLD得接口部分,它们之间接了4245进行电平转换,地址的低2位是不是短路了?那么如果是4245输入端短路了会怎样?是4245的输出端短路了又会怎样?
按照常理,IO口的VH和VL短路,在没有动手测试前,我觉得应该是输出VL。所以这个认识也会否决了问题发现的原因出在这两个IO口上,因为地址线正常输入00,01,10,11,那么短路后输出也应该是00,00,00,11,而不会一下00,11的跳变。但是,事实证明我错了。万用表一测,确实两个IO口短路了(4245的输出端短路),为了验证我的判断,先烧了一个把两个地址线一个拉高一个拉低的代码,再次上电测量,电平大约在1.65V,这个1.65V是要输入CPLD的(3.3V LVTTL电平)。查看了芯片资料,发现>1.7V判断为VIH,而这个基本属于边界值的1.65V都在输入CPLD时被判定为VIH了。所以就出现了最后的现象。
感觉问题一点点解开了,于是扯开两条短路线,重新上电测试,一切步入正轨。看来问题果然如此,两个IO短路的的确确不会只输出一个简单的VL,这个4245就给了一个1.65V,而别的器件若出现这个情况会怎样呢?我不知道,但是有一点现在是可以肯定的,两个IO短路的输出结果需要根据这两个IO的电路本身进行判断。
任何问题都不可以想当然。