FPGA基于VDMA实现任意分辨率视频输出显示,高度贴近真实项目,提供工程源码和技术支持

1、前言

之前写过一篇FPGA纯verilog实现任意分辨率视频输出显示,高度贴近真实项目,提供工程源码和技术支持的文章,讲述了基于AXI协议的FDMA实现任意分辨率视频输出显示,但对于习惯使用zynq或者Microblaze的兄弟来说,更喜欢用VDMA,本设计就是基于VDMA实现任意分辨率视频输出显示,高度贴近真实项目,适用于医疗、军工等图像相关项目。

2、任意分辨率视频输出理论基础

关于理论部分,请参考我之前写的文章:点击查看:任意分辨率视频输出

3、VDMA实现数据缓存

VDMA是Xilinx发布的基于AXIS数据流的图像缓存方案,该IP使用稳定、方便,仅需简单界面配置加SDK配置即可使用,关于VDMA的讲解,Xilinx有官方文档,网上也有各种文档,感兴趣的可以去详细读读,但恕我直言,说多了都是扯淡,读了半天不知道怎么用有意义吗?先用起来再说,在使用过程中去慢慢理解才是最有效的学习方式,就算最后还是不懂也没关系,能用就行,VDMA本身就是一个黑箱IP,你本来就看不到源码,怎么可能真正理解,Xilinx根本就没想让你真正理解;
VDMA界面配置如下:
在这里插入图片描述
在这里插入图片描述
VDMA配置界面几乎不需要更改,保持官方默认配置已经够了,只是buffer深度需要关注一下,比如1080P视频可以适当将buffer深度增大到1024或者2048;还有就是选择缓存帧数,如果嫌延迟太高了可以选择缓存2帧;
拿我的工程去就能直接把VDMA用起来,该IP简单来说就是实现视频到DDR的三帧缓存,使得读写错开,输出完美视频,仅此而已;

4、工程1:Kintex7使用VDMA

开发板:Xilinx Kintex7开发板;
开发环境:Vivado2019.1;
输入:Ov5640摄像头,分辨率由SDK配置;
输出:HDMI,分辨率1920x1080;
Kintex7使用VDMA需要引入Microblaze软核,图像缓存进DDR3;
工程BD如下:
在这里插入图片描述
导出硬件后的代码架构如下:
在这里插入图片描述
SDK主函数如下:

int main(){
	XGpioCfg = XGpio_LookupConfig(AXI_GPIO_DEVICE_ID);
	XGpio_CfgInitialize(&led_gpio, XGpioCfg, XGpioCfg->BaseAddress);
	XGpio_SetDataDirection(&led_gpio, 1, 0);	//output
	XGpio_DiscreteWrite(&led_gpio, 1, 0);
	oak_i2c_init(OV5640_IIC_BASEADDR, 1000000, 0x78>>1, IIC_REG_LEN16, IIC_DATA_LEN8);
	OV5640_Init(OV5640_IIC_BASEADDR,1280,720);
	helai_vdma();
	while(1){
		usleep(500000);
		XGpio_DiscreteWrite(&led_gpio, 1, 1);
		usleep(500000);
		XGpio_DiscreteWrite(&led_gpio, 1, 0);
	}
}

5、工程2:Zynq7100使用VDMA

开发板:Xilinx Zynq7100开发板;
开发环境:Vivado2019.1;
输入:Ov5640摄像头,分辨率由SDK配置;
输出:HDMI,分辨率1920x1080;
VDMA运行与PL端,图像缓存进PS端DDR3,PL端系统时钟由PS提供;
工程BD如下:
在这里插入图片描述
导出硬件后的代码架构如下:
在这里插入图片描述
SDK主函数如下:

void main()
{
	// Initialize OV5640 regesiter
	I2C_config_init();
	//璁剧疆鍐呭瓨涓殑鑳屾櫙
	for(i=0;i<SUM;i++){
		Xil_Out16((VIDEO_BASEADDR0 + i), 0x00);
		Xil_Out16((VIDEO_BASEADDR1 + i), 0x00);
		Xil_Out16((VIDEO_BASEADDR2 + i), 0x00);
	}
	//VDMA_WRITE
	Xil_Out32((VDMA_BASEADDR + 0x030), 0x108B);// enable circular mode
	Xil_Out32((VDMA_BASEADDR + 0x0AC), VIDEO_BASEADDR0);	// start address
	Xil_Out32((VDMA_BASEADDR + 0x0B0), VIDEO_BASEADDR1);	// start address
	Xil_Out32((VDMA_BASEADDR + 0x0B4), VIDEO_BASEADDR2);	// start address
	Xil_Out32((VDMA_BASEADDR + 0x0A8), (H_STRIDE*3));		// h offset (H_STRIDE* 3) bytes
	Xil_Out32((VDMA_BASEADDR + 0x0A4), (H_ACTIVE*3));		// h size (H_ACTIVE * 3) bytes
	Xil_Out32((VDMA_BASEADDR + 0x0A0), V_ACTIVE);			// v size (V_ACTIVE)
	//VDMA_READ
	Xil_Out32((VDMA_BASEADDR + 0x000), 0x8B); 		// enable circular mode
	Xil_Out32((VDMA_BASEADDR + 0x05c), VIDEO_BASEADDR0); 	// start address
	Xil_Out32((VDMA_BASEADDR + 0x060), VIDEO_BASEADDR1); 	// start address
	Xil_Out32((VDMA_BASEADDR + 0x064), VIDEO_BASEADDR2); 	// start address
	Xil_Out32((VDMA_BASEADDR + 0x058), (H_STRIDE*3)); 		// h offset (H_STRIDE * 3) bytes
	Xil_Out32((VDMA_BASEADDR + 0x054), (H_ACTIVE*3)); 		// h size (H_ACTIVE * 3) bytes
	Xil_Out32((VDMA_BASEADDR + 0x050), V_ACTIVE); 			// v size (V_ACTIVE)
	while (1) ;
}

6、上板调试验证并演示

以工程1为例,动态ov5640分辨率500x500演示如下:

K7 500X500 VDMA


以工程2为例,静态ov5640分辨率1280x720演示如下:
在这里插入图片描述
动态ov5640分辨率500x500演示:

FPGA基于VDMA实现任意分辨率视频输出显示

7、福利:工程代码的获取

福利:工程代码的获取
代码太大,无法邮箱发送,以某度网盘链接方式发送,
资料获取方式:私,或者文章末尾的V名片。
网盘资料如下:
在这里插入图片描述

  • 0
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

9527华安

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值