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

news/2024/7/21 6:05:38 标签: fpga开发, 图像处理, VDMA, Zynq, 源码

目录

  • 1、前言
  • 2、任意分辨率视频输出理论基础
  • 3、VDMA实现数据缓存
  • 4、工程1:Kintex7使用VDMA
  • 5、工程2:Zynq7100使用VDMA
  • 6、上板调试验证并演示
  • 7、福利:工程代码的获取

1、前言

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

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

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

VDMA_5">3、VDMA实现数据缓存

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

VDMA_12">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);
	}
}

Zynq7100VDMA_40">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名片。
网盘资料如下:
在这里插入图片描述


http://www.niftyadmin.cn/n/69137.html

相关文章

别学英语了,真的

文 / 王不留&#xff08;微信公众号&#xff1a;王不留&#xff09; 这两年&#xff0c;很多朋友加我微信后&#xff0c;第一句常是&#xff0c;学英语有什么用啊&#xff1f; 我会统一给出真诚答复&#xff1a;没用&#xff0c;真的。 看新闻&#xff0c;中文海量信息已经严重…

【python百炼成魔】python运算符的使用与输入输出函数

文章目录前言一. python 运算符1.1 算术运算符1.2 .赋值运算符1.3 比较运算符1.4. 布尔运算符二. 输入和输出函数2.1 print函数2.1.1 help函数查看帮助文档2.1.2 print的格式化输出2.2 format函数2.3 input数据接收函数写在最后前言 Python 中的运算符主要分为算术运算符、比较…

【java】Spring Boot --spring boot项目整合xxl-job

文章目录1、源码下载地址2.文档地址3.源码结构4.初始化数据库脚本5.配置调度中心xxl-job-admin5.1 修改调度中心配置文件&#xff1a;/xxl-job/xxl-job-admin/src/main/resources/application.properties5.2 启动调度中心5.3 访问调度中心管理界面6.创建执行器项目6.3 载入配置…

代理配置vue.config.js的proxy用法

使用一:mmodule.exports {devServer: {proxy: {/api: http://localhost:3000}} };请求到 /api/xxx 现在会被代理到请求 http://localhost:3000/api/xxx, 例如 /api/user 现在会被代理到请求 http://localhost:3000/api/user使用二如果你想要代码多个路径代理到同一个target下,…

前端高频面试题-JavaScript篇(四)

前端高频面试题-JavaScript篇&#xff08;四&#xff09; &#x1f4bb; 前端高频面试题-JavaScript篇&#xff08;四&#xff09;&#x1f3e0;专栏&#xff1a;前端面试题 &#x1f440;个人主页&#xff1a;繁星学编程&#x1f341; &#x1f9d1;个人简介&#xff1a;一个不…

6.数据类型-列表【Python】

文章目录列表创建列表索引 & 切片基本方法练习列表 ​ Python 的列表类似于 C/C 的数组&#xff0c;但是操作更加灵活。它们没有固定的大小&#xff0c;也没有固定的类型约束。与字符串不同&#xff0c;列表是可变的。 创建列表 ​ 列表由方括号 [] 和分隔列表中的每个元…

Maven生命周期及插件管理

mvn命令 mvn clean package&#xff1a;打包mvn clean install&#xff1a;安装到本地mvn clean deploy&#xff1a;部署到远程私服 生命周期 生命周期---->phase---->plugin goal maven生命周期就是对传统软件项目构件的抽象 清理–》初始化–》编译–》测试–》打包…

【Java】集合迭代器(Iterator)

Iterator对象称为迭代器(设计模式的一种)&#xff0c;主要用于遍历 Collection 集合中的元素。迭代器模式&#xff1a;提供一种方法访问一个容器(container)对象中各个元素&#xff0c;而又不需暴露该对象的内部细节。Collection接口继承了java.lang.Iterable接口&#xff0c;该…