本帖最后由 正点原子运营 于 2023-12-28 15:22 编辑
第四十八章 SD卡读BMP图片HDMI显示实验
1)实验平台:正点原子 ATK-DFPGL22G开发板
2) 章节摘自【正点原子】ATK-DFPGL22G之FPGA开发指南_V1.0
6)FPGA技术交流QQ群:435699340
我们在“SD卡读BMP图片LCD显示实验”中,成功地将SD卡中的BMP图片读出,并将其显示在了LCD屏上。本章我们来学习如何将SD卡中的BMP图片显示在HDMI显示器上。 本章分为以下几个章节: 1.1 简介 1.2 实验任务 1.3 硬件设计 1.4 程序设计 1.5 下载验证
1.1 简介在“SD卡读BMP图片LCD显示实验”的简介部分,我们详细介绍了BMP图片的数据格式;另外在“HDMI彩条显示实验”一章,我们介绍了HDMI接口。如果大家对这两部分的内容不熟悉的话,可以参考相应的章节,此处就不再赘述了。
1.2 实验任务本章的实验任务是使用ATK-DFPGL22G开发板循环读取SD卡中存放的两张BMP格式图片,分辨率为1024*768,并将其显示在HDMI显示器上。
1.3 硬件设计SD卡接口部分的硬件设计请参考“SD卡读写测试实验”中的硬件设计部分。 由于DDR3、SD卡和HDMI接口的引脚数目较多且在前面相应的章节中已经给出它们的管脚列表,这里不再列出管脚分配。
1.4 程序设计根据实验任务我们可以画出本次实验的系统框图,如下图所示。本次实验的框图和“SD卡读BMP图片LCD显示”实验的框图基本相同,只不过移除了SD卡/DDR3参数计算模块,这是因为本次实验的HDMI分辨率固定为1024*768,不需要兼容不同分辨率的LCD液晶屏。 图 48.4.1 SD卡读BMP图片HDMI显示系统框图 图48.4.1是根据本章实验任务画出的系统框图。时钟模块和时钟IP核(HDMI)为其它各模块提供驱动时钟;SD卡读取图片控制模块控制SD卡控制器的读接口,以及将SD卡中读出的RGB888格式数据转换成RGB565格式数据,写入DDR3控制器中;最后HDMI顶层模块从DDR3控制器中读出图片数据,显示到HDMI显示器上。 FPGA顶层模块(sd_bmp_hdmi)例化了以下六个模块:时钟模块(clock)、时钟IP核模块(HDMI)、SD卡读取图片控制模块(sd_read_photo)、SD卡控制器模块(sd_ctrl_top)、DDR3控制器模块(ddr3_top)和HDMI顶层模块(hdmi_top)。 顶层模块(sd_bmp_hdmi):顶层模块主要完成对其余各模块的例化,实现各模块之间的数据交互。需要注意的是,系统初始化完成是在SD卡以及DDR3都初始化完成后才开始拉高的,该信号控制着SD卡读取图片控制模块的复位信号,因此SD卡读取图片控制模块是在系统初始化完成后才工作的,防止因SD卡或者DDR3初始化未完成导致数据错误。 时钟模块(pll_clk):时钟模块通过调用时钟IP核实现,共输出4个时钟,频率分别为75Mhz、375Mhz、50Mhz和50Mhz(相位偏移180度)时钟。75Mhz时钟和375Mhz时钟作为HDMI顶层模块的驱动时钟;50Mhz时钟和50Mhz(相位偏移180度)作为SD卡读取图片控制模块、SD卡控制器模块的驱动时钟。 SD卡读取图片控制模块(sd_read_photo):SD卡读取图片控制模块通过控制SD卡控制器的读接口,从SD卡中读取图像数据,并在读完一张图片后延时一段时间,再去读取另一张图片数据,实现两张图片的循环切换读取。 SD卡控制器模块(sd_ctrl_top):SD卡控制器模块负责驱动SD卡,该模块将SD卡的SPI读写操作封装成方便用户使用的接口。有关该模块的详细介绍请大家参考“SD卡读写测试实验”章节。 DDR3控制器模块(ddr3_top):DDR3读写控制器模块负责驱动DDR3片外存储器,缓存从SD卡中读出的图像数据。该模块将DDR3复杂的读写操作封装成类似FIFO的用户接口,非常方便用户的使用。有关该模块的详细介绍请大家参考“DDR3读写测试实验”章节。 时钟IP核模块(pll_hdmi):时钟模块通过调用时钟IP核实现,共输出两个时钟,频率分别为65Mhz和325Mhz。 HDMI顶层模块(hdmi_top):HDMI顶层模块负责驱动HDMI显示器的驱动信号的输出。 本次实验的所有模块在前面相应的章节中都有做详细的介绍,这里就不再赘述了。这里需要注意顶层模块参数的定义,代码如下: - 50 //parameter define
- 51 //DDR3读写最大地址 1024 * 768 = 786432
- 52 parameter DDR3_MAX_ADDR =786432;
- 53 //SD卡读扇区个数 1024 * 768 * 3 / 512 + 1 = 4609
- 54 parameter SD_SEC_NUM =4609;
复制代码顶层模块定义的参数DDR_MAX_ADDR和SD_SEC_NUM,分别对应DDR3的读写最大地址(最小地址从0开始)和SD卡的读扇区个数。HDMI顶层模块固定输出HDMI的分辨率为1024*768,所以DDR_MAX_ADDR的值为1024*768=786432;SD卡单张图片的数据量是1024*768*24b,一个扇区是512个字节,共需要读出1024*768*24/(512*8)= 1024*768*3/512=4608个扇区,由于BMP图片文件除有效图像数据外,还有共54个字节的文件头+信息头,所以需要多读一个扇区,即4069。
1.5 下载验证在打开下载界面之前,我们还需要先做一些准备工作,也就是向SD卡中拷贝两张BMP图片。我们向大家准备好了BMP的图片,位于该工程sd_bmp_hdmi\doc\风景图片\目录下,如下图所示。 我们提供的BMP图片分辨率为1024*768,和程序中输出的HDMI分辨率一致。需要说明的是,由于BMP图片的扫描方式是从左到右,从下到上,因此HDMI显示器显示的图片和SD卡中存放的BMP图片是颠倒的。为了使HDMI显示的图片为正,所以上图文件里也提供了在原图的基础上旋转180度的图片,所以本次实验拷贝的图片是fengjing1_1024x768_旋转180度.bmp和fengjing2_1024x768_旋转180度.bmp。 接下来将TF(Micro SD)卡连接读卡器,读卡器连接电脑,此时可以通过电脑对TF卡中的文件进行存取。这里需要注意的是,SD卡在经过多次存放数据与删除数据之后,存入的文件有可能不是按照连续的扇区地址存储的,为了避免图片显示错误,我们将BMP图片拷贝至SD卡之前,先把SD卡格式化,格式化的设置如下图所示,然后点击开始按钮完成格式化。 接下来我们将对应的两个BMP图片拷贝到SD卡中,拷贝完成后如下图所示: 文件拷贝完成后,接下来我们使用WinHex工具软件查看这两个文件的扇区起始地址,该工具位于开发板所随附的资料盘(A盘)中“6_软件资料/1_软件/WinHex”目录下,双击“WinHex.exe”或者“WinHex64.exe”打开软件。软件打开后,在菜单栏中点击“工具”,然后点击“打开磁盘”,如下图所示。 注意:如果提示缺少管理员权限,是否重新程序WinHex,选择“是”,然后重新选择“打开磁盘”。 在“物理驱动器”下,我们看到上图标记位2的地方有RM2、Generic STORAGE DEVICE(14.8GB,USB)的字样,该物理驱动器对应的是TF卡,标号为RM2,我们找到标号RM2在逻辑驱动器中的位置,即箭头1所指的地方,选中后点击“确定”按钮即可查看文件的起始扇区地址,打开后的界面如下图所示: 图 48.5.6 WinHex查看扇区起始地址界面 由上图可知,两张BMP图片的起始扇区地址分别为1051072和1046400,其中第一扇区地址是指物理扇区号,如果软件中显示的扇区地址与物理扇区号不一致,需要以右下角物理扇区号的地址为准!需要修改的代码如下: - 37 //parameter define
- 38 //设置两张图片的扇区地址,通过上位机WinHex软件查看
- 39 parameter PHOTO_SECTION_ADDR0 = 32'd1046400;//第一张图片扇区起始地址
- 40 parameter PHOTO_SECTION_ADDR1 = 32'd1051072;//第二张图片扇区起始地址
复制代码如果在WinHex软件查看的值不是代码里定义的值,需要将代码中定义的这两个参数值改成WinHex查看的扇区地址,然后重新编译工程。 接下来我们将TF卡插入开发板的SD卡插槽,注意带有金属引脚的一面朝下;然后将HDMI连接线一端与ATK-DFPGL22G开发板上的HDMI接口连接,另一端连接HDMI显示器。最后将下载器一端连接电脑,另一端与开发板上的JTAG下载口连接,如下图所示。 接下来我们打开电源开关并下载程序。程序下载完成后,此时HDMI显示器上循环切换显示TF卡中的两张图片,说明TF卡图片显示实验(HDMI显示)下载验证成功。如图48.5.8所示: |