《DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南》第二十五章 SD卡读BMP图片HDMI显示实验​
  95kVyaJuybju 2023年11月12日 20 0

SD卡读BMP图片HDMI显示实验​

在“SD卡读BMP图片LCD显示实验”中成功地将SD卡的BMP图片读出,并将其显示在了LCD屏上们将学习如何SD卡中的BMP图片显示在HDMI显示器上。

本章包括以下几个部分:

  1. 简介
  2. 实验任务
  3. 硬件设计
  4. 软件设计
  5. 下载验证


简介

在“SD卡读BMP图片LCD显示实验”的简介部分,我们详细介绍了BMP图片的数据格式;另外在《MPSOC FPGA开发指南》HDMI彩条显示实验”一,我们介绍了HDMI接口如果大家对这两部分的内容不熟悉的话,可以参考相应的章节就不再赘述

实验任务

本章的实验任务是使用MPSOC开发板读取SD卡中存放的BMP格式图片分辨率为1920*1080,并将其显示在HDMI显示上。

硬件设计

根据实验任务我们可以画出本次实验的系统框图,如下图所示:

《DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南》第二十五章 SD卡读BMP图片HDMI显示实验​_框图


25.3.1 系统框图

25.3.1与“SD卡读BMP图片LCD显示实验”中的系统框图基本相同,只是将驱动LCD显示rgb2lcd模块替换成了本次实验中的DVI Transmitter用于驱动HDMI接口;另外还删除了用于读取LCD ID信息的AXI GPIO模块。因此本次实验的硬件设计部分在“SD卡读BMP图片LCD显示实验”的基础上稍作修改即可。

首先要删除《SD卡读BMP图片LCD显示实验》工程中的rgb to lcd模块AXI GPIO两个模块,以及LCD相关的接口。如25.3.2所示,我们要删除图中橙色高亮的两个模块和4个接口:

《DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南》第二十五章 SD卡读BMP图片HDMI显示实验​_IP_02


25.3.2 删除LCD相关模块

由于本次实验通过HDMI显示器显示图片,分辨率固定为1080P(1920*1080),因此时钟IP核可以固定输出三路时钟提供给DVI_Transmitter模块,且取消勾选动态重配置的功能,时钟IP核的配置修改如下图所示:

《DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南》第二十五章 SD卡读BMP图片HDMI显示实验​_#include_03


25.3.3 取消动态重配置选项

《DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南》第二十五章 SD卡读BMP图片HDMI显示实验​_框图_04


25.3.4 时钟输出界面

时钟IP核共输出三路时钟,频率分别为148.5Mhz、371.25Mhz和742.5Mhz,用于连接至DVI_Transmitter模块。需要注意的是,对于“4EV”器件来说,其速度等级为“-1”,时钟IP核能够输出的最大时钟频率为667Mhz。当配置的时钟高于此频率时,会有一个警告,提示时序可能不满足,不过适当超频通常不影响其功能,因此可直接忽略此警告。

接下来添加DVI Transmitter IP核。该IP核位于工程目录下的ip_repo文件夹中名为“DVI_TX”。我们需要将其添加到工程IP库,添加IP核的方法大家参考“自定义IP核-呼吸灯实验”。添加完成后,我们要在Block Design连接DVI Transmitter模块的接口信号,引出外部端口(只需要引出TMDS端口,而tmds_oen是预留的端口信号,浮空即可)具体的连接方式如25.3.5

《DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南》第二十五章 SD卡读BMP图片HDMI显示实验​_IP_05


25.3.5 添加并连接DVI_Transmitter IP

需要说明的是,本次实验的硬件框图是基于《SD卡读BMP图片LCD显示实验》搭建的,VDMA的AXI Stream格式数据流和Memory Map格式数据流的时钟频率设置的较低,为100Mhz,因此VDMA和DDR4的数据交互速率会受到限制,即支持的HDMI显示分辨率无法达到很高,实测最大能达到的分辨率为1280x800

对于LCD屏的显示实验来说,达到1280x800的分辨率已经够用了,但是考虑到目前大多数的HDMI显示器支持1080P(1920x1080)的分辨率,我们需要对底层搭建的硬件环境做修改,才能支持1080P分辨率。考虑到本手册HDMI显示相关的例程不需要1080P分辨率,且大多数HDMI显示例程是基于LCD例程修改而来,如果每次都为了兼容1080P分辨率而修改底层硬件环境比较麻烦,因此本手册仅本章实验的底层硬件环境支持1080P分辨率,其它HDMI实验大家如果有1080P分辨率的显示需求,可以按照本章实验进行修改

底层硬件修改的方法是将VDMA的AXI Stream格式数据流和Memory Map格式数据流的时钟频率改为150Mhz,而VDMA的配置端口不需要太高的频率,可以仍然保持100Mhz

首先双击打开“Zynq UltraScale+ MPSOC”框图,点击“Clock Configuration”,在“PL Fabric Clocks”一栏下勾选PL1,时钟频率设置为150Mhz。设置完成后,点击“OK”按钮,如下图所示:

《DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南》第二十五章 SD卡读BMP图片HDMI显示实验​_IP_06


25.3.6 添加“PL1”时钟

修改完成后,可以发现“Zynq UltraScale+ MPSOC”框图多了一个pl_clk1端口。接下来删除pl_clk0连线,首先选中pl_clk0的连线使其高亮,然后按下键盘的“Delete”进行删除,如25.3.725.3.8所示:

《DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南》第二十五章 SD卡读BMP图片HDMI显示实验​_框图_07


25.3.7 选中pl_clk0连线

《DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南》第二十五章 SD卡读BMP图片HDMI显示实验​_IP_08


25.3.8 删除pl_clk0连线

然后删除框图中的AXI Interconnect IP核(ps8_0_axi_periph)、AXI SmartConnect IP核(axi_smc)和Processor System Reset IP核(rst_ps8_0_99M),框图删除后,如下图所示。

《DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南》第二十五章 SD卡读BMP图片HDMI显示实验​_#include_09


25.3.9 删除IP

接下来连接pl_clk1的时钟,如下图所示。

《DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南》第二十五章 SD卡读BMP图片HDMI显示实验​_框图_10


25.3.10 连接pl_clk1时钟

然后点击“Run Connnection Automation”,下面列出了会自动连接的模块及其接口,勾选“All Automation”,然后点击“OK”按钮。

此时系统会自动生成AXI Interconnect AXI SmartconnectAXI Interconnectps8_0_axi_periph)用于桥接MPSOC处理器M_AXI_HPM0_LPD接口和外部低速外设的AXI_LITE接口AXI Smartconnectaxi_smc)用于连接MPSOC处理器的S_AXI_HP0_FPD接口和VDMAM_AXI_MM2S总线。另外系统也自动生成了两个 reset模块(rst_ps8_0_99Mrst_ps8_0_149M),用于复位总线上的外设。

整体系统架构图如下:

《DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南》第二十五章 SD卡读BMP图片HDMI显示实验​_#include_11


25.3.11 整体系统架构连接图

Block Design修改完成后保存,然后重新Generate Output Products和“Create HDL Wrapper”。接下来我们还要修改约束文件,为HDMI接口分配引脚。打开工程中名为“pin.xdc”的约束文件,并将原先LCD相关的约束语句删除,替换成以下内容:

set_property -dict {PACKAGE_PIN G3 IOSTANDARD LVDS} [get_ports {TMDS_tmds_data_p[2]}]

set_property -dict {PACKAGE_PIN F2 IOSTANDARD LVDS} [get_ports {TMDS_tmds_data_p[1]}]

set_property -dict {PACKAGE_PIN G1 IOSTANDARD LVDS} [get_ports {TMDS_tmds_data_p[0]}]

set_property -dict {PACKAGE_PIN E1 IOSTANDARD LVDS} [get_ports TMDS_tmds_clk_p]

保存约束文件,然后选择“Generate Bitstream”重新生成BIT文件。

软件设计

本次实验的软件工程“SD卡读BMP图片LCD显示实验”略有不同,如下图所示:

《DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南》第二十五章 SD卡读BMP图片HDMI显示实验​_框图_12


25.4.1 软件工程

25.4.1红色方框中的文件夹名为“display_ctrl_hdmi”,它在前面实验中“display_ctrl”的基础上删除了GPIO相关的函数及变量。在本次实验中删除了AXI GPIO模块,因此要删除这些函数和变量,否则会报错。

本次实验的代码如下所示:

1 #include <stdio.h>​
2 #include <stdlib.h>​
3 #include <string.h>​
4 #include "xil_types.h"​
5 #include "xil_cache.h"​
6 #include "xparameters.h"​
7 #include "xaxivdma.h"​
8 #include "xaxivdma_i.h"​
9 #include "display_ctrl_hdmi/display_ctrl_hdmi.h"​
10 #include "vdma_api/vdma_api.h"​
11 #include "ff.h"​
12 ​
13 //宏定义​
14 #define VDMA_ID XPAR_AXIVDMA_0_DEVICE_ID //VDMA器件ID​
15 #define DISP_VTC_ID XPAR_VTC_0_DEVICE_ID //VTC器件ID​
16 ​
17 //函数声明​
18 void load_sd_bmp(u8 *frame);​
19 ​
20 //全局变量​
21 XAxiVdma vdma;​
22 DisplayCtrl dispCtrl;​
23 VideoMode vd_mode;​
24 //frame buffer的起始地址​
25 unsigned int const frame_buffer_addr = (XPAR_PSU_DDR_0_S_AXI_BASEADDR + 0x1000000);​
26 ​
27 int main(void)​
28 {​
29 xil_printf("HDMI Display 1920*1080 \r\n");​
30 ​
31 //设置 video 参数,分辨率: 1920*1080​
32 vd_mode = VMODE_1920x1080;​
33 ​
34 //配置VDMA​
35 run_vdma_frame_buffer(&vdma, VDMA_ID, vd_mode.width, vd_mode.height,​
36 frame_buffer_addr,0, 0,ONLY_READ);​
37 ​
38 //初始化Display controller​
39 DisplayInitialize(&dispCtrl, DISP_VTC_ID);​
40 //设置VideoMode​
41 DisplaySetMode(&dispCtrl, &vd_mode);​
42 DisplayStart(&dispCtrl);​
43 ​
44 //读取SD卡图片并显示​
45 load_sd_bmp((u8*)frame_buffer_addr);​
46 return 0;​
47 }​
48 ​
49 //从SD卡中读取BMP图片​
50 void load_sd_bmp(u8 *frame)​
51 {​
52 static FATFS fatfs;​
53 FIL fil;​
54 u8 bmp_head[54];​
55 UINT *bmp_width,*bmp_height,*bmp_size;​
56 UINT br;​
57 int i;​
58 ​
59 //挂载文件系统​
60 f_mount(&fatfs,"",1);​
61 ​
62 //打开文件​
63 f_open(&fil,"fengjing.bmp",FA_READ);​
64 ​
65 //移动文件读写指针到文件开头​
66 f_lseek(&fil,0);​
67 ​
68 //读取BMP文件头​
69 f_read(&fil,bmp_head,54,&br);​
70 xil_printf("fengjing.bmp head: \n\r");​
71 for(i=0;i<54;i++)​
72 xil_printf(" %x",bmp_head[i]);​
73 ​
74 //打印BMP图片分辨率和大小​
75 bmp_width = (UINT *)(bmp_head + 0x12);​
76 bmp_height = (UINT *)(bmp_head + 0x16);​
77 bmp_size = (UINT *)(bmp_head + 0x22);​
78 xil_printf("\n width = %d, height = %d, size = %d bytes \n\r",​
79 *bmp_width,*bmp_height,*bmp_size);​
80 ​
81 //读出图片,写入DDR​
82 for(i=*bmp_height-1;i>=0;i--){​
83 f_read(&fil,frame+i*(*bmp_width)*3,(*bmp_width)*3,&br);​
84 }​
85 ​
86 //关闭文件​
87 f_close(&fil);​
88 ​
89 Xil_DCacheFlush(); //刷新Cache,数据更新至DDR中​
90 xil_printf("show bmp\n\r");​
91 }

可以看出,本次实验的程序与“SD卡读BMP图片LCD显示实验”非常相似,只是删除了读取LCD ID相关的内容。有关这部分代码的详细介绍请大家参考“SD卡读BMP图片LCD显示实验”,此处不再赘述。需要注意的是,本次实验在SD卡中放置的图片分辨率为1920*1080,因此在程序的第32行,视频参数设置成VMODE_1920x1080

下载验证

首先我将下载器与开发板上的JTAG接口连接,下载器另外一端与电脑连接然后使用USB连接线将USB UART接口(PS_PORT)与电脑连接,用于口通信

我们在工程目录下新建了一个名为“风景图片”的文件夹,把其中名为“fengjing.bmp”的图片拷贝SD卡的根目录下,然后SD卡插入开发板背面的卡槽另外还需要使用HDMI连接线HDMI显示连接到开发板上的HDMI接口,最后连接开发板的电源。

在Vitis软件下方的Vitis Terminal窗口中点击右上角的来设置连接串口。然后下载本次实验硬件设计过程中所生成的BIT文件,对PL进行配置。最后下载软件程序下载完成后,在下方的Vitis Terminal中可以看到应用程序打印的信息,如下图所示:

《DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南》第二十五章 SD卡读BMP图片HDMI显示实验​_#include_13


25.5.1 串口打印信息

25.5.1打印出了BMP文件的文件和信息头等信息从数据中计算出BMP图片的宽度为1920高度为1080与我们入SD中的BMP图片一致。

时HDMI显示上显示存入SD卡中示例图片,25.5.2示,说明本次实验在MPSOC开发板上面下载验证成功。

《DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南》第二十五章 SD卡读BMP图片HDMI显示实验​_IP_14


25.5.2 下载验证

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月12日 0

暂无评论

推荐阅读
  QtpjMRSUUfXb   2023年12月08日   37   0   0 引脚#include看门狗
  Vn37uiKQIsdv   2023年12月06日   13   0   0 网络层链路IP
  tprTMCWDkFAR   2023年12月07日   12   0   0 头文件#include初始化
  tprTMCWDkFAR   2023年12月06日   23   0   0 用户名APIIP
  QtpjMRSUUfXb   2023年12月06日   20   0   0 卷积#includeCUDA
  UYSNSBVoGd8R   2023年12月08日   13   0   0 引脚#include#define
95kVyaJuybju