ZYNQ图像处理(1)——vdma_hdmi显示环境搭建

2023-05-16

1、引言

FPGA是一种现场可编程逻辑门阵列,其并行的特点让其在图像处理、数字通信等领域有广泛的应用。FPGA缺点是不擅长流程控制,对于IIC、SPI等通信方式,往往需要用到状态机。ZYNQ7000是赛灵思推出的一款带有ARM核的FPGA,包含了两个ARM A9的核以及FPGA资源,分为PS端和PL端。在运用ZYNQ做图像处理之前,有必要先搭建环境。我用的是ZYNQ7010,vivado是2018.3版本的。

2、显示环境硬件搭建

2.1 工程框架

利用ZYNQ7010显示图像,其工程的框架我们可以参照赛灵思应用手册xapp742,手册中有这样一张图,描述了 整个工程的各个模块。它是基于FPGA K7开发板搭建的,其实对于ZYNQ也相似。VDMA是video direct memory access,是一种可以将数据从地址映射转为数据流的IP核,RGB to YCrCb、OSD等式图像处理模块,这里未用到,VTC和Stream to video bridge是一起使用的,VTC是动态时钟管理,用于给Stream to video bridge提供时钟信号,Stream to video bridge则是将VDMA的数据流转换成RGB格式可以供LCD屏或者HDMI屏幕显示,具体可以看手册。
在这里插入图片描述

2.2 设计目标和工程建立

这里我们需要先在PS端往DDR中写入数据,之后通过VDMA在hdmi显示屏上显示一个彩条图案。在知道了设计的基本框架和目标后,我们画出这个工程的简图,之后创立vivado工程。
这里我自己画了一个工程的简化后的框图,PS端主要完成了DDR的配置,以及串口通信还有往DDR中写入彩条数据。PL端与PS端通过GP和HP接口进行交互,HP接口读取DDR中数据,传输到VDMA,VDMA实现地址映射到数据流转换,VIDEO OUT实现axi数据流到显示屏可以显示的数据转换。这里GP接口是配置,VDMA的一些参数,VTC和PLL分别是时钟配置和锁相环。
在这里插入图片描述
工程这边就按照自己的开发板型号来建立即可,之间创建block design,第一步添加ZYNQ IP核如下。需要对他做一些简单的配置,包括DDR、UART等,DDR和串口根据自己板子型号设置即可,这边为了能让传输快一些,将FCLK时钟频率改为了100M,此外,还添加了HP接口来作为数据的传输接口。
在这里插入图片描述
修改完成之后的zynq IP核如下图所示。
在这里插入图片描述

2.3 VDMA ip核简介和配置

创建完了工程后,根据框架简图,首先添加VDMA IP核如下图所示。关于VDMA IP核的使用可以参考塞琳思的手册pg020。
在这里插入图片描述
AXI VDMA IP核提供了一种高带宽的地址映射到数据流的转换,这个IP的基本框图如下图所示,左边是地址映射接口,可以将DDR数据读取出来,右边是数据流格式,AXI4-Lite可以对IP核进行配置。
在这里插入图片描述
之后对该IP核进行配置,其配置完了的界面如下图所示。address width是地址长度,frame buffer是帧缓存。由于这里只是读取ddr数据进行显示,所以只勾选了VDMA的读通道,读通道包含四个参数地址映射宽度、最大突发长度、数据流格式、行缓存深度。数据流是24位是因为传输的是RGB888的图像,一个像素24位,行缓存深度是2048,一般大于你的显示屏即可,我这边使用的是1024×768的hdmi屏。
在这里插入图片描述
在这里插入图片描述
配置完了IP后我们将VDMA ip和ZYNQ连接起来,如下图所示。可以看到,vivado为我们填加了三个额外的IP,分别是同步复位、AXI互联接口、AXI智慧互联接口。这样子,我们就实现了从PS端到VDMA的地址映射数据传输的模块搭建。
在这里插入图片描述

2.4 VTC ip核与Video OUT ip核简介与配置

这两个IP核的参考手册分别是PG016和PG044。针对手册内容,不在过多叙述,这里直接vivado添加了这两个IP。Video out ip如下图所示,其主要接口为video_in:接入vdma输出的数据流,vtiming_in:用于接收VTC IP给出的时序,此外,还有两组时钟和复位信号。主要的输出端口vid_io_out:输出LCD屏幕可以显示的信号,包括行同步、场同步等。
在这里插入图片描述
在这里插入图片描述
此外,还需要添加VTC模块如下图所示。其主要输入接口包括了时钟、复位、使能,输出包括时序信号输出等。对它的配置如下,首先是取消勾选了AXI接口,因这里没有用到;然后关闭了detection。之后,因为这这边显示屏是768p的,所以选择1024×768。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在添加完了IP后,继续在block design中连线完成设计,连接完的框图如下图所示。将VDMA的流数据接到Video out,VTC为Video out提供显示的时序信号。Video out的aclk为100M,此外还注意到,video out和VTC还有一个显示屏显示时钟,这个时钟得根据不同的显示屏来确定。
在这里插入图片描述

2.5 PLL ip和DVI ip添加和配置

因为显示屏显示是需要具体的时钟信号,所以我们这里手动添加了一个PLL ip核,用于给VTC和Video out提供显示时钟。除此之外,Video out的时序是LCD的,还需要添加一个自定义的IP核来完成lcd到hdmi的转换。添加的两个IP如下图所示。这边用锁相环产生了两个时钟,一个是65MHz,对应我的显示屏,另一个是325MHz,是65MHz的5倍,满足hdmi的时序对时钟信号的要求。最后完成连线如下图所示,之后对工程综合实现生成bit流导入到sdk进行软件设计。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3、显示环境软件程序

整个程序也十分简单,在sdk中导入vdma显示的例程。利用run_triple_frame_buffer函数初始化VDMA,初始化的参数包括了VDMA实例、VDMA的ID、宽度、高度、vdma起始地址。之后写入彩条数据即可。

#include "stdio.h"
#include "xparameters.h"
#include "xaxivdma.h"
#include "vdma_api.h"
#include "xil_cache.h"

#define VDMA_ID	XPAR_AXIVDMA_0_DEVICE_ID
#define BASE_ADDR	XPAR_PS7_DDR_0_S_AXI_BASEADDR
#define WIDTH	1024
#define DEPTH	768

int vdma_addr=(BASE_ADDR+0x1000000);

int main()
{
	int i,j;
	u8* vdma_buffer;
	XAxiVdma vdma_inst;
	vdma_buffer=(u8*) vdma_addr;

	run_triple_frame_buffer(&vdma_inst,VDMA_ID, WIDTH,DEPTH,vdma_addr,0,0);
	for(j=0;j<DEPTH;j++)
	{
		for(i=0;i<WIDTH;i++)
		{
			if(i>=0 && i<WIDTH/3)
			{
				*(vdma_buffer+j*WIDTH*3+3*i+0)=0x00;
				*(vdma_buffer+j*WIDTH*3+3*i+1)=0x00;
				*(vdma_buffer+j*WIDTH*3+3*i+2)=0xff;
			}
			else if(i>=WIDTH/3 && i<WIDTH/3*2)
			{
				*(vdma_buffer+j*WIDTH*3+3*i+0)=0x00;
				*(vdma_buffer+j*WIDTH*3+3*i+1)=0xff;
				*(vdma_buffer+j*WIDTH*3+3*i+2)=0x00;
			}
			else if(i>=WIDTH/3*2 && i<WIDTH)
			{
				*(vdma_buffer+j*WIDTH*3+3*i+0)=0xff;
				*(vdma_buffer+j*WIDTH*3+3*i+1)=0x00;
				*(vdma_buffer+j*WIDTH*3+3*i+2)=0x00;
			}
		}
	}
	Xil_DCacheFlush();
	return 0;
}

4、VDMA彩条显示效果图

在这里插入图片描述

5、添加动态时钟IP核的工程

上面的一个工程针对的是某个固定的屏幕,当我们想要更换屏幕时,底层的模块就要重新配置,然后再重新生成比特流,比较麻烦。因此,下述的框架对上面的工程做了修改,首先是删除了锁相环IP核,添加了动态时钟配置模块;其次,打开VTC模块的AXI接口,使其可以通过PS端进行配置;然后VTC、Video out以及DVI模块的时钟由动态时钟模块提供。最后完成所有连线。
在这里插入图片描述
最后进行SDK软件设计,其代码如下所示,配置VDMA以及彩条显示与上面的代码相似。差别是添加了一些Display controller的函数对VTC模块和Dyclk模块进行配置和初始化。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "xil_types.h"
#include "xil_cache.h"
#include "xparameters.h"
#include "xaxivdma.h"
#include "xaxivdma_i.h"
#include "display_ctrl/display_ctrl.h"
#include "vdma_api/vdma_api.h"

//宏定义
#define BYTES_PIXEL        3                          //像素字节数,RGB888占3个字节
#define DYNCLK_BASEADDR    XPAR_AXI_DYNCLK_0_BASEADDR //动态时钟基地址
#define VDMA_ID            XPAR_AXIVDMA_0_DEVICE_ID   //VDMA器件ID
#define DISP_VTC_ID        XPAR_VTC_0_DEVICE_ID       //VTC器件ID

//函数声明
void colorbar(u8 *frame, u32 width, u32 height, u32 stride);

//全局变量
XAxiVdma     vdma;
DisplayCtrl  dispCtrl;
VideoMode    vd_mode;
//frame buffer的起始地址
unsigned int const frame_buffer_addr = (XPAR_PS7_DDR_0_S_AXI_BASEADDR + 0x1000000);
unsigned int lcd_id=0;        //LCD ID

int main(void)
{
	vd_mode=VMODE_1024x768;

	//配置VDMA
	run_vdma_frame_buffer(&vdma, VDMA_ID, vd_mode.width, vd_mode.height,
							frame_buffer_addr,0, 0,ONLY_READ);

    //初始化Display controller
	DisplayInitialize(&dispCtrl, DISP_VTC_ID, DYNCLK_BASEADDR);
    //设置VideoMode
	DisplaySetMode(&dispCtrl, &vd_mode);
	DisplayStart(&dispCtrl);

	//写彩条
	colorbar((u8*)frame_buffer_addr, vd_mode.width,
			vd_mode.height, vd_mode.width*BYTES_PIXEL);
    return 0;
}

//写彩条函数(彩虹色)
void colorbar(u8 *frame, u32 width, u32 height, u32 stride)
{
	u32 color_edge;
	u32 x_pos, y_pos;
	u32 y_stride = 0;
	u8 rgb_r, rgb_b, rgb_g;

	color_edge = width * BYTES_PIXEL / 7;
	for (y_pos = 0; y_pos < height; y_pos++) {
		for (x_pos = 0; x_pos < (width * BYTES_PIXEL); x_pos += BYTES_PIXEL) {
			if (x_pos < color_edge) {                                           //红色
				rgb_r = 0xFF;
				rgb_g = 0;
				rgb_b = 0;
			} else if ((x_pos >= color_edge) && (x_pos < color_edge * 2)) {     //橙色
				rgb_r = 0xFF;
				rgb_g = 0x7F;
				rgb_b = 0;
			} else if ((x_pos >= color_edge * 2) && (x_pos < color_edge * 3)) { //黄色
				rgb_r = 0xFF;
				rgb_g = 0xFF;
				rgb_b = 0;
			} else if ((x_pos >= color_edge * 3) && (x_pos < color_edge * 4)) { //绿色
				rgb_r = 0;
				rgb_g = 0xFF;
				rgb_b = 0;
			} else if ((x_pos >= color_edge * 4) && (x_pos < color_edge * 5)) { //青色
				rgb_r = 0;
				rgb_g = 0xFF;
				rgb_b = 0xFF;
			} else if ((x_pos >= color_edge * 5) && (x_pos < color_edge * 6)) { //蓝色
				rgb_r = 0;
				rgb_g = 0;
				rgb_b = 0xFF;
			} else if ((x_pos >= color_edge * 6) && (x_pos < color_edge * 7)) { //紫色
				rgb_r = 0x8B;
				rgb_g = 0;
				rgb_b = 0xFF;
			}
			frame[x_pos + y_stride + 0] = rgb_b;
			frame[x_pos + y_stride + 1] = rgb_g;
			frame[x_pos + y_stride + 2] = rgb_r;
		}
		y_stride += stride;
	}
	Xil_DCacheFlush();     //刷新Cache,数据更新至DDR3中
	xil_printf("show color bar\r\n");
}

最后显示的效果如下图,从左到右依次红橙黄绿青蓝紫。
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ZYNQ图像处理(1)——vdma_hdmi显示环境搭建 的相关文章

  • 头文件包含顺序

    头文件包含顺序 原理 xff1a 当通过 include指令包含另一个头文件时 xff0c 编译预处理器用头文件的内容取代 include指令 xff0c 也就是说 xff0c 头文件的所有内容最终都会被合并到某一个或某几个源文件中 xff
  • 计算机网络(五): ros下socket编程示例

    ros下socket编程示例 服务器端 span class token macro property span class token directive keyword include span span class token str
  • 三种方式实现:进度条

    1 Bootstrap实现进度条 bootstrap min css下载地址 xff1a https cdn staticfile org twitter bootstrap 3 3 7 css bootstrap min css boot
  • 物理端口与逻辑端口

    若 1 端口 端口可分为物理端口与逻辑端口 所谓逻辑端口指的是计算机内部或交换机路由器内的端口 xff0c 看不见 xff0c 摸不着 所谓物理端口 xff0c 就是可见的端口 xff0c 像 xff1a 交换机路由器集线器 RJ11端口
  • RS485接收数据后发送乱码

    序 最近调块板子上面有几路485 xff0c 控制芯片STM32F407VE 转换芯片ADM2587 xff0c 使用485转换器连接电脑 xff0c 发现串口助手向板子发送数据后会收到乱码 xff0c 经软硬件联合调试排除bug 一 问题
  • python urllib.parse

    urlparse span class token keyword from span urllib span class token punctuation span parse span class token keyword impo
  • HTTP学习(5)--demo编写(1)

    一个基于Java的HTTP服务器demo 前面几篇博客 xff0c 大致介绍了几个方面的例子 xff0c 例如报文解析 报文组装等 现在打算将这些东西集合起来 xff0c 编写一个小HTTP服务器demo 期间遇到了很多问题 xff0c 也
  • 用Python写一个监督你刷李永乐考研题目的简单小程序

    import datetime import xlwings import math month 61 datetime datetime now strftime 39 m 39 date 61 datetime datetime now
  • 对于遗传算法,谈谈个人看法

    最近在学习遗传算法 xff0c 小有体会 这个用数学方法来模拟生物学过程的算法实在是有很多值得玩味的地方 遗传算法要干什么 xff1f 比如Z 61 f x y 我们要找到他在x 0 1 y 0 1 区间上的最大值 我们就先随机在x 0 1
  • AD(altium designer)软件的基础使用(硬件的一些总结,写的有些乱,高手请略过)

    1 快捷键 xff1a Ctrl 43 R 复制并重复粘贴 Shift 43 c 取消选择 Space 逆时针旋转对象 Shift 43 space 顺时针旋转对象 X 水平翻转对象 Y 垂直翻转对象 G切换捕捉栅格 V F View中的F
  • C++字节转换 (byte转int 互转)(BCD和HEX转换)

    2个字节short int 高低位转化 short int y 61 0x7f21 y 61 y amp 0xff00 gt gt 8 y amp 0x00ff lt lt 8 printf 34 x 34 y 用short型变量储存 xf
  • 王者荣耀-数模论文分享(虽然结果我自己都不信)

    基于基础数据的王者荣耀英雄强度评估及英雄设计 摘要 王者荣耀是当下很火爆的一款手机游戏 xff0c 如何基于当下的双方阵容选择合适的英雄来获得胜利 xff0c 是一个值得探讨的问题 xff0c 现基于游戏数据对于各个英雄的强度进行建模评估
  • 用蚁群算法求解TSP问题

    TSP是什么 xff1f TSP全称Travelling salesman problem 中文名 xff1a 旅行商问题 就是模拟退火中讲到的14个城市之间巡回旅行 xff0c 求路径最短的问题 为什么偏偏找他呢 xff1f 因为这是一个
  • python 语法小进阶1

    1 filter 是通过生成 True 和 False 组成的迭代器将可迭代对象中不符合条件的元素过滤掉 xff1b 而 map 返回的则是 True 和 False 组成的迭代器 gt gt gt res1 61 map lambda n
  • 焊接的技巧与方法

    手工焊接操作的基本步骤 1 清洁焊接对象的表面 xff0c 这一步是必须的 xff0c 就算你再赶时间也不能偷懒 用小刀或者砂纸把焊点打磨光亮 xff0c 露出铜的光泽 铜表面的氧化物会阻碍焊锡与之形成合金 xff0c 这一步做得不到位的话
  • 计算机网络体系结构

    计算机网络体系结构 一 计算机网络概述计算机网络的概念 组成与功能概念 xff1a 计算机网络 功能 xff1a 数据通信 连通性 资源共享分布式处理 信息综合处理 提高可靠性 负载均衡 发展的三个阶段组成 xff1a 物理组成 xff1a
  • 嵌入式技术基础与实践(第4版)

    1 5 2020 开放权限 在此之前 xff0c 防报告查重 嵌入式系统概述 嵌入式系统常用术语 嵌入式系统常用的C语言基本语法概要 M0 43 体系结构与指令系统简介 存储映象 中断源 硬件最小系统 GPIO及基本打通原理 程序的基本调试
  • 串行通信基础知识与UART驱动构件使用方法

    串行通信基础 串行通信接口 异步串行通信 UART 常称为 串口 或SCI xff0c 在USB未普及之前 xff0c 是PC机必备通信接口之一 通信方式为单字节通信 xff0c 是最简单的串行通信方式 RS232 RS485 接线简单 x
  • ARM Cortex-M0+中断机制与中断编程步骤

    中断基础知识 为什么需要使用中断 xff1f 如果通过查询接收标志查看一个字节是否收到 xff0c 则需要时刻花费CPU等资源 但中断机制能够在收到一个字节后 xff0c 通知CPU把收到的字节取走 异常 xff1a CPU强行从正常运行的
  • 计算机网络体系结构

    一 计算机网络概述 计算机网络的概念 组成与功能 概念 功能 组成 工作方式 分类 计算机网络的标准化工作及相关组织 标准分类 计算机网络的标准化工作 相关组织 二 计算机网络体系结构与参考模型 计算机网络分层结构 计算机网络体系结构 为什

随机推荐

  • KL25嵌入式实验考核

    KL25嵌入式实验考核 xff08 6 43 xff09 404 页面找不到 说明资源在审核中 1 利用 KL25 小板实现 控制红色 LED 灯每隔 2 秒钟亮暗变换的同时 在 PC 机上显示 MCU 的计时时间 xff0c MCU 的初
  • 自制PMW3901光流模块

    PMW3901光流Sensor体积小 功耗低 精度高 xff0c 效果非常好 xff0c 自己做了一个光流小模块带TOF测距 xff0c 使用Pixracer 43 PX4固件 xff0c 测试效果还不错 测试视频 xff1a https
  • 模数转换ADC模块

    通用基础知识 ADC模块是嵌入式应用中重要的组成部分 xff0c 是嵌入式系统与外界连接的纽带 xff0c 是在测控系统中的重要内容 ADC模块 xff1a 即模数转换模块 AD转换模块 xff0c 功能是将电压信号转换为相应的数字信号 实
  • 实验五 Flash在线编程实验

    一 xff0e 实验目的 xff08 1 xff09 掌握 Flash 存储器在线编程的基本概念 xff08 2 xff09 熟悉 Flash 存储器的在线编程擦除和写入的步骤 xff08 3 xff09 进一步深入理解 MCU 和 C 串
  • Install OpenCV+ Python in Ubuntu

    1 VMware安装ubuntu 不建议在Windows下学习 安装教程 Tip1 xff1a Ubuntu安装结束后无法正常联网 然后就是等待漫长的更新 Tip2 文件含有中文名 打开终端 export LANG 61 en US xdg
  • Tracking motion in video

    Tracking motion in video Download the source code to Ball Tracking with OpenCV
  • parse command line arguments

    parse command line arguments
  • 计算机网络

    计算机网络 一 计算机网络体系结构 二 物理层 三 数据链路层 四 网络层 五 运输层 六 应用层
  • 【c++初学】遇到问题:对xxx未定义的引用

    在编译的时候遇到了 未定义引用 root 64 czp span class token operator span PC span class token operator span span class token operator s
  • 在同一个浏览器上打开同一个网址只打开一个窗口的方法

    具体问题看图吧 xff0c 我自己也说不清楚 具体操作如下 xff1a target属性的功能之一是可以在同一个浏览器中只打开被标记相同的网页窗口 利用这一功能可以实现以上问题 target属性链接地址 xff1a http www w3s
  • esp32 Arduino IDE读取航模接收机SBUS信号

    库函数下载链接https download csdn net download qq 40925542 87207281 该库函数适用于具有多个串口的开发板 xff0c esp32中测试通过 xff0c 测试代码如下 xff1a inclu
  • curl 401 unauthorized解决

    用curl获取web信息时遇到了401unauthorized错误 用下面的命令解决了 xff1a span class token function curl span insecure anyauth u admin password
  • git自建服务器-借助蒲公英实现远程访问

    git自建服务器 借助蒲公英实现远程访问 本文涉及蒲公英组网 xff0c 这里大家可以参考蒲公英官网组网教程 使用的硬件 蒲公英x3a 路由器 xff1a 用于智能组网 xff0c 实现内网穿透vpn功能 xff1b orange pi3
  • sockaddr与sockaddr_in结构体简介

    span class token keyword struct span sockaddr span class token punctuation span span class token keyword unsigned span s
  • ROS入门(二)——创建功能包和工作空间

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 前言一 工作空间 xff08 workspace xff09 xff1f 二 创建工作空间 xff08 workspace xf
  • SpringBoot异常处理-SimpleMappingExceptionResolver(四)

    异常处理 SimpleMappingExceptionResolver 配置 SimpleMappingExceptionResolver 处理异常 在全局异常类中添加一个方法完成异常的同一处理 结果是只不返回参数 没有上一个博客方法好 但
  • Matplotlib三维绘图,这一篇就够了

    Matplotlib三维绘图 xff0c 这一篇就够了 1 效果图1 1 3D线效果图1 2 3D散点效果图1 3 3D随机颜色散点效果图1 4 3D散点不同mark点效果图1 5 3D线框效果图1 6 3D曲面不透明效果图1 7 3D曲面
  • C++编程永不过时的语言,原因何在?

    想要知道C 43 43 到底如何你首先要了解C 43 43 的特性 C 43 43 既保留了C语言的有效性 灵活性 便于移植等全部精华和特点 xff0c 又添加了面向对象编程的支持 xff0c 具有强大的编程功能 xff0c 可方便地构造出
  • px4ctrl代码解读-px4ctrl_node

    头文件 include lt ros ros h gt include 34 PX4CtrlFSM h 34 include lt signal h gt 1 初始化节点 ros init argc argv 34 px4ctrl 34 r
  • ZYNQ图像处理(1)——vdma_hdmi显示环境搭建

    1 引言 FPGA是一种现场可编程逻辑门阵列 xff0c 其并行的特点让其在图像处理 数字通信等领域有广泛的应用 FPGA缺点是不擅长流程控制 xff0c 对于IIC SPI等通信方式 xff0c 往往需要用到状态机 ZYNQ7000是赛灵