手把手教你从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://www.toymoban.com/news/detail-812238.html
实验结果如图所示
文章来源地址https://www.toymoban.com/news/detail-812238.html
到了这里,关于【【手把手教你从SD卡驱动VDMA显示图片实验】】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!