什么是定位LCD花屏显示问题的第一大法?

大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家分享的是上LCD花屏显示问题的分析解决经验。

痞子衡最近这段时间在参与一个基于的大项目(先保个密),需要做一个开机动画功能,板子连接的LCD屏分辨率是1280x480,因为开机动画要求达到30fps,并且要画质清晰,如果是从SD卡里读mp4或者jpeg去解码,这么高分辨率的图像(暂不考虑低分辨率的图片再用PXP模块去拉伸的方案)解码耗时比较长,恐怕难以达成30fps,所以痞子衡打算直接把图片的裸rgb数据事先存在Flash里,然后LCD模块直接去刷Flash里的数据去显示。

板子上的SPINORFlash有两种,默认是八线DDR高性能Flash,还有一个可选的四线SDR普通Flash,痞子衡做好的代码在默认高性能Flash上跑得没问题,换到另一块rework为普通四线Flash上就出问题了,显示完全是花屏,没有一点图片的影子,到底是怎么回事?跟着痞子衡一起去发现答案吧。

一、项目板卡简图

先来看一下这个项目板卡简图,简图里只示意了痞子衡今天要分享的LCD问题相关的器件,显示屏是TM103XDKP13控制器驱动的LVDS接口屏,跟连接的话需要有一个RGB2LVDS转接。Flash都是选的旺宏的,一个是MX25UW51345(200MHz,8bit,DDR),还有一个是MX25U25645(133MHz,4bit,SDR)。此外还有两个16bit的W9825G6KH组成的32bitSDRAM做显存,总容量是64MB。

二、在Flash中准备好图片裸数据

首先我们需要在Flash中存入图片数据,1280x480-24bpp(rgb888)图片一张的裸数据大小是1800KB,32MB的Flash最大可以存18张图片,为了给程序存储留点空间,我们就存17张,从Flash偏移0x100000处开始存图片。

2.1截取一段mp4视频2.2使用ScreenToGif软件分离出图片

这时候可以用非常好用的GIF制作软件ScreenToGif打开这个1秒的MP4,可以看到一共有31张图片,可以删掉其中一些留下17张,然后将其保存为图片(当前版本仅能保存为png格式),可以再用格式工厂软件将图片格式转为jpg,存在D:/nxp_logo文件夹下。

2.3Python脚本转成rgb888裸数据

有了17张jpg图片,这时候写一个Python脚本(),借助Image库将17张jpg图片中的rgb数据全部抽取出来保存在一个bin文件中,下面脚本使用命令为:/nxp_logo/-ostartup_video_white_rgb888_17。

importsys,osimportargparseimportImageparser=(formatter_class=)_argument("-o","--output",required=True,metavar="PATH",type=('wb'))_argument("input",help="JPEGImagefolder.")args=_argsimgFiles=使用Image库打开jpg图片imgObj=(imgFiles[idx])pixelBuf=_FB_HEIGHT480defineAPP_FB_BPP3constuint32_ts_imagePics=17;constuint32_ts_imageStartAddr=0x30100000;intmain(void){uint8_t*imageAddr=(uint8_t*)s_imageStartAddr;uint32_timageBytes=APP_FB_HEIGHT*APP_FB_WIDTH*APP_FB_BPP;BOARD_ConfigMPU;BOARD_InitBootPins;BOARD_BootClockRUN;BOARD_ResetDisplayMix;APP_InitDisplay;while(1){/*Waitfortheprevioussetframebufferactive.*/while(s_newFrameShown==false);/*Nownewframeisready,passittoLCDIF.*/s_newFrameShown=false;g_(g_dc,0,imageAddr);imageAddr+=imageBytes;if((uint32_t)imageAddr=(s_imageStartAddr+imageBytes*s_imagePics)){break;}}}staticvoidAPP_BufferSwitchOffCallback(void*param,void*switchOffBuffer){s_newFrameShown=true;}

这时候把代码下载进高性能DDRFlash的那块板子,我们的代码可以链接到TCM里执行,这样不占用运行时Flash访问带宽,不与LCD抢带宽。断电重启可以看到在60Hz的LCD刷新率下,开机动画效果显示杠杠的。

现在把代码下载进普通SDRFlash的板子试试,可以看到LCD显示花屏了,完全没有图像的影子,这时候该怎么定位问题?

四、尝试降低LCD刷新率

在尝试降低LCD刷新率之前,痞子衡额外做了一些debug工作来确认是不是Flash焊接的问题,首先是调试器挂上去查看PC指针停在哪里,经调试发现,PC指针是在TCM里,根据工程map文件可以查到其地址对应的是程序的结尾,说明代码正常跑完了,这至少证明芯片能够正常从Flash启动。

然后痞子衡又对程序作了一些改动,将Flash中的图片数据拷贝到SDRAM中,让LCD模块去刷SDRAM,这时候图像显示是正常的,这几乎就可以定位问题了,是普通SDRFlash带宽不够,Flash访问速度撑不起60Hz刷新率。

defineDEMO_HBP(48U)defineDEMO_VSW(1U)defineDEMO_VFP(5U)staticvoidBOARD_InitLcdifClock(void){/**Thepixelclockis(height+VSW+VFP+VBP)*(width+HSW+HFP+HBP)*framerate.**For60Hzframerate,theTM103XDKP13pixelclockshouldbe40MHz.**/constclock_root_config_tlcdifv2ClockConfig={.clockOff=false,.mfn=0,.mfd=0,.mux=4,/*!PLL_528.*/.div=12,};CLOCK_SetRootClock(kCLOCK_Root_Lcdifv2,lcdifv2ClockConfig);}

让我们尝试降低LCD刷新率来验证是不是Flash带宽的问题,在BOARD_InitLcdifClock函数中修改的值,慢慢增大该值,经痞子衡测试,当div设为22时(即对应LCD刷新率为33.9Hz),终于能够正常显示开机动画了。

五、关于带宽的分析

现在给出痞子衡的观点,对于一个新项目,如果首次测试LCD显示,建议先从低刷新率开始,只有低刷新率调试通过,再逐渐增大刷新率,否则会因为带宽问题浪费不少时间。

最后再让我们通过理论公式来推算这款普通SDRFlash能支持最大的刷新率,计算公式其实很简单:

LCD最大刷新率=(Flash时钟频率*Flash数据位)/图片大小=133MHz*4bit/(1280*480*24bit)=36.08Hz

理论计算值36.08Hz跟我们实测值33.9Hz很接近,那点差值应该是FLEXSPI和eLCDIF模块的开销。

至此,上LCD花屏显示问题的分析解决经验痞子衡便介绍完毕了,掌声在哪里~~~

版权声明:本站所有作品(图文、音视频)均由用户自行上传分享,仅供网友学习交流,不声明或保证其内容的正确性,如发现本站有涉嫌抄袭侵权/违法违规的内容。请举报,一经查实,本站将立刻删除。

相关推荐