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实现任意分辨率视频输出显示文章来源:https://www.toymoban.com/news/detail-521053.html
7、福利:工程代码的获取
福利:工程代码的获取
代码太大,无法邮箱发送,以某度网盘链接方式发送,
资料获取方式:私,或者文章末尾的V名片。
网盘资料如下:
文章来源地址https://www.toymoban.com/news/detail-521053.html
到了这里,关于FPGA基于VDMA实现任意分辨率视频输出显示,高度贴近真实项目,提供工程源码和技术支持的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!