【【手把手教你从SD卡驱动VDMA显示图片实验】】

发布时间:2024年01月21日

手把手教你从SD卡驱动VDMA显示图片实验

图像格式介绍

典型的BMP图像文件是由四部分组成的
包括了BMP的文件头,BMP信息头,调色板,位图数据
因为传递的是RGB图像 RGB不太需要调色板了 从信息头直接到位图数据

在这里插入图片描述
文件头占据了14个字节
分别是
在这里插入图片描述
查看这个16进制格式 BMP的文件格式 总是低字节的放在低地址位,高字节放在高地址位。
可以查看到如下的二进制
在这里插入图片描述
前2字节 0x4d42 是 代表了图片的类型是 BM
后面的4字节 0x00_11_94_36 是 代表了字节的大小
后面的合起来4字节 保留都是 0x00_00_00_00
最后的4字节是代表了从文件开始到真正的数据的偏移量 0x36 代表了54个字节
记住这里的是0ah 的位置
这里一共合计14个字节

下面的一共 40个字节 用来表示BMP数据头的信息
在这里插入图片描述
在这里面最主要关注的就是上面的
bitWidth 图像宽度
bitHeight 图像高度
bitBitCount 图像位深
bitSizeImage 图像大小

整个架构block design 的连接参照
VDMA与HDMI的连接

需要修改的是 zynq核
启用SD的连接
在这里插入图片描述
在这里插入图片描述
注意修改电平 不然会被烧坏整个SD卡
整体的block design 构建如下
其实和上一节的 block design是一样的
在这里插入图片描述
启动vitis

我的src只有3个文件
因为输出的是720p的图像 我并没有参照例程做
我的main.c有两版都可以运行

第一个main.c

#include"stdio.h"
#include "stdlib.h"
#include "string.h"
#include"xparameters.h"
#include"vdma_api.h"
#include "xaxivdma.h"
#include "xil_types.h"
#include "xil_cache.h"
#include "ff.h"
#define   VDMA_ID        XPAR_AXI_VDMA_0_DEVICE_ID      // VDMA ID
#define   DDR_ADDRESS    XPAR_PS7_DDR_0_S_AXI_BASEADDR  // DDR的基地址 0x00100000
#define   WIDTH          1280
#define   HEIGHT         720
int       frame_buffer_addr   =   DDR_ADDRESS + 0x10000000   ;
void load_sd ( u8 * frame);
int main()
{
Xil_DCacheDisable();
    XAxiVdma vdma_inst;  // 这是例化的驱动实例


// 往VDMA的帧缓存写入图案
//先写SD卡

    // 配置并启动VDMA
    run_triple_frame_buffer(
            &vdma_inst,        // VDMA 驱动实例
            VDMA_ID,           // VDMA 器件ID
             WIDTH,             // 图像宽度
            HEIGHT,            // 图像高度
            frame_buffer_addr, // VDMA帧缓存的起始地址
            0,
            0);

load_sd((u8*)frame_buffer_addr);
}
void load_sd ( u8 * frame)
{
//先定义一个 FATFS 的 文件系统
static     FATFS fatfs;
FIL     fil;
UINT     *bmp_width,*bmp_height;
UINT     br;
int     i;
u8 bmp_head[54];
//挂载文件系统
printf("%d\n",f_mount(&fatfs,"",1));

//打开文件
f_open(&fil,"xiaoeyu.bmp",FA_READ);   //FA_READ 表示只读的形式
xil_printf("show1\n\r");
//移动文件读写指针到文件开头
f_lseek(&fil,54);
xil_printf("show2 \n\r");

f_read(&fil,bmp_head,54,&br);

 //打印 BMP 图片分辨率和大小
 bmp_width = (UINT  *)(bmp_head + 0x12);
 bmp_height = (UINT *)(bmp_head + 0x16);

 //printf("%d,%d\n",*bmp_width, *bmp_height);

// f_lseek(&fil,54);
//读出图片,写入DDR
for(i=*bmp_height-1;i>=0;i--){
    f_read(&fil,frame+i*(*bmp_width)*3,(*bmp_width)*3,&br);

}
//关闭文件
f_close(&fil);
    xil_printf("show bmp\n\r");

}

第二版main.c

#include"stdio.h"
#include "stdlib.h"
#include "string.h"

#include"xparameters.h"
#include"vdma_api.h"

#include "xaxivdma.h"
#include "xil_types.h"
#include "xil_cache.h"

#include "ff.h"



#define   VDMA_ID        XPAR_AXI_VDMA_0_DEVICE_ID      // VDMA ID
#define   DDR_ADDRESS    XPAR_PS7_DDR_0_S_AXI_BASEADDR  // DDR的基地址 0x00100000
#define   WIDTH          1280
#define   HEIGHT         720
int       frame_buffer_addr   =   DDR_ADDRESS + 0x10000000   ;
void load_sd ( u8 * frame);


int main()
{


	Xil_DCacheDisable();
		XAxiVdma vdma_inst;  // 这是例化的驱动实例


	// 往VDMA的帧缓存写入图案
	//先写SD卡

		// 配置并启动VDMA
		run_triple_frame_buffer(
				&vdma_inst,        // VDMA 驱动实例
				VDMA_ID,           // VDMA 器件ID
			 	WIDTH,             // 图像宽度
				HEIGHT,            // 图像高度
				frame_buffer_addr, // VDMA帧缓存的起始地址
				0,
				0);
load_sd((u8*)frame_buffer_addr);
}



void load_sd ( u8 * frame)
{
	//先定义一个 FATFS 的 文件系统
	static 	FATFS fatfs;
	FIL 	fil;
	UINT 	*bmp_width,*bmp_height;
	UINT 	br;
	int 	i;
	//u8 bmp_head[54];


	//挂载文件系统
	printf("%d\n",f_mount(&fatfs,"",1));

	//打开文件
	f_open(&fil,"xiaoeyu.bmp",FA_READ);   //FA_READ 表示只读的形式
	xil_printf("show1\n\r");
	//移动文件读写指针到文件开头
	f_lseek(&fil,0);
	xil_printf("show2 \n\r");

	//f_read(&fil,bmp_head,54,&br);

	 //打印 BMP 图片分辨率和大小
	 bmp_width = (UINT  *)(&fil + 0x12);
	 bmp_height = (UINT *)(&fil + 0x16);

	 //printf("%d,%d\n",*bmp_width, *bmp_height);

     f_lseek(&fil,54);
	//读出图片,写入DDR
	for(i=*bmp_height-1;i>=0;i--){
		f_read(&fil,frame+i*(*bmp_width)*3,(*bmp_width)*3,&br);
}
	//关闭文件
		f_close(&fil);

		xil_printf("show bmp\n\r");

}

接下来的vdma_api.c

我在两处禁用了写使能端口
在这里插入图片描述
在这里插入图片描述

vdma_api.h

#include "xaxivdma.h"
#include "xparameters.h"
#include "xil_exception.h"


int run_triple_frame_buffer(XAxiVdma* InstancePtr, int DeviceId, int hsize,
		int vsize, int buf_base_addr, int number_frame_count,
		int enable_frm_cnt_intr) ;

在这里插入图片描述

实验结果如图所示

在这里插入图片描述

文章来源:https://blog.csdn.net/weixin_50965981/article/details/135730357
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。