本帖最后由 1nnocent 于 2023-2-20 23:26 编辑
1、 总体设计
1.1 设计要求
- 母板读取SD卡中图片(图片分辨率为800*480);
- 将图片存入DDR中;
- 将DDR中的图片数据发送到子板;
- 子板接收母板发送的数据进行缩放;
- 将缩放后的图片进行lcd显示,lcd屏的分辨率为480*272。
1.2 总体结构框图
1.3 系统参数计算
1、Ram*2中缓存lcd乒乓显示的数据,lcd显示一行数据包括消隐所用的时间为:525/12.5MHz=55us;
2、Lcd显示一行数据的时间内需要发送完两行参考像素由缩放模块处理完并存到另一个ram中供lcd下次乒乓操作显示。
缩放时钟:525/12.5M = 800*2/f2(f2 = 38.09MHz),实际测试时缩放时钟要使用40MHz。
2、 模块设计
该系统主要分为两个部分,分别为母板和子板两个部分。其中母板部分主要负责读取SD卡中的图片数据,并存储到DDR中,最后将DDR中的图片数据发送到子板中处理;子板部分主要负责将母板发送的数据进行缩放处理,并将缩放后的数据缓存到ram中,最后将ram中的数据通过lcd显示模块显示缩放后的图片。
2.1.1 SD卡和DDR控制模块
母板部分的SD卡和DDR控制模块与正点原子lcd屏读取SD卡bmp图片并显示例程部分较相近,这里不进行过多的阐述。需要注意的是例程工程中根据使用的lcd屏读取相应分辨率的图片,项目中lcd显示的图片和SD卡读取的图片不是同一个分辨率,所以该部分需要删除根据lcd分辨率读取相应图片的功能,改成SD卡固定读取800*480的图片,项目使用的lcd屏分辨率为480*272.
2.1.2 发送数据模块
2.1.2.1 发送数据模块简单描述
因为lcd显示图像时存在消隐信号,所以母板给数据时不能连续地给子板发送数据,否则会导致数据的丢失。需要一定的发送数据时序来满足lcd显示数据的需求,即lcd需要显示数据时母板向子板发送足够的数据,lcd消隐期间停止发送数据,以免数据的丢失。
2.1.2.2 内部实现
为了配合lcd显示数据时的消隐期,母板向子板发送数据时需要一定的发送时序,该时序类似lcd屏的消隐期。发送数据的时序主要分为两个部分,第一部分为帧开始时需要发送两行参考像素,因为lcd显示每帧数据的开始时,两个ram中均没有数据(两个ram在lcd显示时进行乒乓操作),所以需要在帧开始信号之后利用消隐期将这两行参考数据发送出去,有缩放模块处理完并存到ram中缓存。
如上图所示在检测到场信号的上升沿(pos_vsync)之后马上发送两行数据(共800*2=1600个像素),这样在开始乒乓操作之前就已经将其中一个ram准备好数据。
母板向子板发送数据的第二个部分为lcd乒乓显示其中一个ram中的数据时间内再发送两行参考像素,实现乒乓操作。
注:此次缩放的缩放比为2:1,所以两行参考像素进行缩放输出一行缩放数据。母板发送数据的时序是每次发送两行参考像素,lcd在显示一行缩放后数据的时间内母板要发送完成两行参考像素。
发送数据的时序第二部分如上图所示,先对lcd_req请求信号进行计数,以0、1、2为周期,即lcd显示三行数据的时间,母板发送数据时需要在这个周期之内完成发送,如图所示母板发送四行数据(1024*4)所用的时间不到2.5个lcd请求,在三个请求时间内完成数据的发送。上述为缩放比为4:3时的发送时序,当缩放比为2:1时发送时序类似。
2.2.1 缩放模块
2.2.1.1 缩放算法简单描述
双线型内插值算法利用原图像中虚拟点四周的四个真实存在的像素值来共同决定目标图中的一个像素值对于一个目的像素,设置坐标通过反向变换得到的浮点坐标为(i+u,j+v) (其中i、j均为浮点坐标的整数部分,u、v为浮点坐标的小数部分,是取值[0,1)区间的浮点数),则这个像素得值 f(i+u,j+v) 可由原图像中坐标为 (i,j)、(i+1,j)、(i,j+1)、(i+1,j+1)所对应的周围四个像素的值决定,即:
f(i+u,j+v) =(1-u)*(1-v)*f(i,j) + (1-u)*v*f(i,j+1) + u*(1-v)*f(i+1,j) + u*v*f(i+1,j+1)
因为缩放比为2:1时四个参考像素生成一个像素,此时u,v的值都为零,由上述公式可知缩放后的像素为f(I,j)即左上角的参考像素。所以对于缩放比为2:1的缩放场景可以对原参考像素进行计数,四个为一组,每组选择左上角的参考像素即为缩放后的像素,可以不用进行乘法器的运算,该方式值使用于缩放比为2:1时的场景。
2.2.1.2 内部实现
缩放算法需要两行数据中四个相邻的参考像素进行缩放,所以需要两个ram来缓存参考像素,这两个ram进行乒乓操作。该项目中缩放比为2:1,所以每四行参考像素可以生成3行缩放数据。将一帧图像的每行数据按0、1、2、3为周期进行计数,则一帧图像各行数据在两个ram中的位置如下所示:
入上图所示如果当前写入ram中的数据的行计数为0时不能进行缩放操作(因为缩放算法需要两行参考像素),当前写入ram中的数据的行计数为1时可以进行缩放操作。当前写入ram中的数据之行计数为1时读取第0和1行的四个参考数据进行缩放,且缩放后的数据为第0行的第一个参考像素。
2.2.2.1 ram缓存模块功能介绍
Ram缓存模块主要缓存lcd屏幕需要显示的像素数据,该模块一共有两个ram,每个ram的大小为400*1*16bit,ram的大小根据缩放比和图片大小来确定,缩放的原图大小为800*480,缩放比为2:1,所以lcd显示三行数据需要400*1*16bit大小的ram缓存空间。两个ram乒乓操作完成完整一帧数据的显示。
2.2.2.2 内部实现
该模块主要开辟两个大小为400*1*16bit大小的ram来缓存lcd需要显示的数据,该模块缓存数据的思想与缩放模块缓存两行参考像素的思想一致,可以参考《2.2.1.3内部实现》部分。
2.2.3 lcd显示模块
该模块用于显示缩放后的图像,因为缩放的原始图像和使用的lcd屏幕尺寸的长宽比不一致,所以缩放后的图像不能填满整个lcd屏幕。所以需要对lcd屏幕进行裁剪,将缩放后的数据显示在屏幕的正中间,多余的地方使用白色填充。该功能的实现只需要判断当前显示的坐标是否在有效显示区域内,是则显示缩放后的数据,否则使用白色进行填充。
3、调试过程
3.1 LCD图像显示花屏
LCD屏显示图像出现花屏时主要有两个方面的因素。一方面是给到屏幕的数据源与屏幕的尺寸不匹配导致;另一方面是行场时序不正确导致LCD屏幕显示不正确。下图的显示场景中边框白色为裁剪后丢弃的图像部分(800*480到480*272的缩放场景中缩放前后的图像长宽比不一致,所以缩小后的图像会比LCD屏略小,多余的部分进行裁剪),图中边框显示正常,排除上述第二种行场时序的情况。此现象需要分辨率为800*480的图片数据源。
LCD1
3.2 LCD显示画面分成几部分
因为时间原因还未找到具体原因,等工作没那么忙了继续查找问题,这里先记录一下现象:
LCD2
源码:这个版本的代码的现象和上一个视频有一定的差别,有做一定的调试,但暂时还没解决问题。