0
点赞
收藏
分享

微信扫一扫

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

Mhhao 2023-03-03 阅读 77

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

在前面的例程中大家已经学会了SD卡读写,DP彩条显示等实验,那么本节实验将带领大家一起学习如何将SD卡中的BMP图片读取出来通过Mini DP接口显示到显示屏上(这里使用Mini DP转HDMI线实现Mini DP信号转HDMI信号并在HDMI显示屏上显示)。

本章包括以下几个部分:

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



简介

因为SD卡读取BMP图片和DP显示在前面的“SD卡读取BMP图片LCD显示实验”和“DP彩条显示实验”中都有过详细的介绍了,这里就不再重复赘述。

实验任务

在SD卡中存储一张BMP图片,使用MPSOC开发板读取这张图片信息并通过Mini DP接口在HDMI显示屏上显示出来(注意要连接转接线)。

硬件设计

关于SD卡和Mini DP接口的硬件设计在前文“SD卡读取BMP图片LCD显示实验”和“DP彩条显示实验”中都有过详细的介绍,这里就不再重复赘述了。

软件设计

本节实验是在DP彩条实验的基础上添加了SD卡读BMP的功能。因此我们只需要在DP彩条实验的硬件平台上将SD卡硬件勾选上(步骤见SD卡读写实验),然后我们就可以打开Vitis了。在Vitis中我们需要添加SD卡的文件系统(步骤见SD卡读写实验),添加完SD卡的文件系统后我们来修改DP彩条实验的代码。

在DP彩条显示实验中GraphicsOverlay函数作为产生彩条的数据源函数,而在本节实验中这个函数已经没有用了,因此我们把这个函数替换成一个新的SD卡读BMP图片的函数(load_sd_bmp)作为DP显示的数据源。

load_sd_bmp函数如下所示:

1 void load_sd_bmp(u8 *frame)​
2 {​
3 static FATFS fatfs;​
4 FIL fil;​
5 u8 bmp_head[54];​
6 UINT *bmp_width,*bmp_height,*bmp_size;​
7 UINT br;​
8 int i;​
9 short y,x;​
10 u32 dp_picture_addr = 0;​
11 //挂载文件系统​
12 f_mount(&fatfs,"0:/",1);​
13 ​
14 //打开文件​
15 f_open(&fil,"fengjing.bmp",FA_READ);​
16 ​
17 //移动文件读写指针到文件开头​
18 f_lseek(&fil,0);​
19 ​
20 //读取BMP文件头​
21 f_read(&fil,bmp_head,54,&br);​
22 xil_printf("fengjing.bmp head: \n\r");​
23 for(i=0;i<54;i++)​
24 xil_printf(" %x",bmp_head[i]);​
25 ​
26 //打印BMP图片分辨率和大小​
27 bmp_width = (UINT *)(bmp_head + 0x12);​
28 bmp_height = (UINT *)(bmp_head + 0x16);​
29 bmp_size = (UINT *)(bmp_head + 0x22);​
30 xil_printf("\n width = %d, height = %d, size = %d bytes \n\r",​
31 *bmp_width,*bmp_height,*bmp_size);​
32 ​
33 //读出图片,写入DDR ​
34 dp_picture_addr = (*bmp_height-1)*LINESIZE ;​
35 ​
36 for(y = 0; y < *bmp_height ; y++)​
37 {​
38 f_read(&fil, read_line_buf, *bmp_width * 3, &br);​
39 for(x = 0; x < *bmp_width; x++)​
40 {​
41 frame[x * 4 + dp_picture_addr + 0] = read_line_buf[x * 3 + 2];​
42 frame[x * 4 + dp_picture_addr + 1] = read_line_buf[x * 3 + 1];​
43 frame[x * 4 + dp_picture_addr + 2] = read_line_buf[x * 3 + 0];​
44 frame[x * 4 + dp_picture_addr + 3] = 0xff ;​
45 }​
46 dp_picture_addr -= LINESIZE;​
47 }​
48 ​
49 //关闭文件​
50 f_close(&fil);​
51 ​
52 xil_printf("show bmp\n\r");​
53 }

看到这个函数我相信大家一定步陌生了,这个函数就是前面“SD卡读取BMP图片LCD显示实验”中用到的读取SD卡图片的函数。只不过在本节实验中对其进行了简单的修改。

大家注意看代码第34~47行,这段代码有两个作用,一个是将BMP图片的BGR格式转换成DP显示的RGBA格式,另一个作用是将图片的第一行数据放在DDR显存区的最后一行(由于BMP文件存储数据时,图像的扫描方式是按从左到右、从下到上的顺序,因此如果我们直接将一整幅图片存入DDR显存,那么最终显示出来的将是一个上下颠倒的图片)。下面我们来分析一下这两个功能具体是如何实现的。

在DP彩条显示实验中我给大家讲解了DP显示的途径,就是将要显示的图像从缓存中搬运到DP帧缓冲区域,并且配置FrameBuffer要显示的图像大小即可。在本节实验中我们先把BMP图片从SD卡中读取出来缓存进DDR,按照之前的思路我们只需要将DDR存储图片第一个像素的地址frame_buffer_addr配置给FrameBuffer就可以显示了。但是实际上我们这么干显示的画面是不正常的,因为第一点是像素数据格式不一样,DP控制器默认的像素格式是RGBA而BMP图片的像素格式是BGR。除此之外如果不添加任何操作,实际上读入DDR的图片是一个颠倒的图片。那么接下来就要解决这两个问题。

代码第34行定义了一个地址常量dp_picture_addr,它的实际数值就是图片的高度减一乘以长度再乘以四即(1080-1)*1920*4,这个数值实际含义就是一帧图片去掉最后一行剩下的图像占有的最大空间字节地址。然后再看代码第38行用到了一个read_line_bufread_line_buf就是一个大小为1920*3的数组,说白了就是BMP图片一行像素数据占用的总字节地址大小,使用f_read函数将SD卡中图片的每一行数据先读出来缓存进read_line_buf数组。最后就是代码第41~44行了,这几行代码先将BMP图片像素的BGR格式转成RGB格式,并且将透明度A赋常值0xff,然后将第X行的数据放到X+dp_picture_addr行中去。例如读出的是第一行数据则放到最后一行中去,第一行读完后dp_picture_addr会自减1个LINESIZE,读第二行数据时就将数据放到倒数第二行去,然后dp_picture_addr再自减1个LINESIZE,依次类推,当dp_picture_addr减到最后一个LINESIZE时刚好图片读取到最后一行,这样就实现了图片颠倒。通过这种方式就实现了将SD卡中BMP图片完整的搬运到了frame_buffer_addr中去,并且将图片的像素格式和上下颠倒都调整好了。此时就可以把frame_buffer_addr配置给FrameBuffer了。

到这里关于SD卡读取BMP图片DP显示的代码就讲解完了,关于其他部分代码和DP彩条显示实验一模一样,这里就不再重复赘述了。

下载验证

首先我们将下载器与MPSOC开发板上的JTAG接口连接,下载器另外一端与电脑连接。然后使用USB连接线将开发板USB_UART接口与电脑连接,用于串口通信,然后将DP转接线连接到HDMI线,再连接至HDMI显示屏(这里需要使用主动式转换器,并不是所有的转接线都通用,请大家前往正点原子官方店铺购买),最后开发板上的启动模式开关的四个开均拨到(都置为ON设置为JTAG模式并将含有名为“fengjing.bmp”的BMP格式图片(注意分辨率是1920*1080且图片命名要与代码中调用一致)的SD卡插入最后连接开发板电源给开发板上电。如下图所示:

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


26.5.1 硬件连接图

然后下载代码,稍等一会,显示屏上即可显示SD卡中BMP的图案,如下图所示,说明实验成功。

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


26.5.2 下载验证


举报

相关推荐

0 条评论