基于EBAZ4205矿板的图像处理:03摄像头采集HDMI输出视频图像

基于EBAZ4205矿板的图像处理:03摄像头采集HDMI输出视频图像

先看效果

请添加图片描述
请添加图片描述

项目简介

  1. 我是使用的EBAZ4205矿板,超级大电工的转接板和我自己买的一块没有xclk的ov5640完成的该项目,没有设备需自备。
  2. 我就是跑通了正点原子的开源代码(下文会提供路径和链接),我感觉直接把正点原子的代码下载下来,然后改一下引脚就可以。但是我建议照着他们的代码和文档,自己搭一遍(我也是这么做的),因为一是我的vivado版本是2021.2,和他的vivado版本不同,二也是为了学习嘛。
  3. 本项目,设置OV5640输出分辨率为1280*720 ,PCLK = 72Mhz

项目内容

我的代码和正点原子的只有三处不同

  1. 许多IP版本不一致,所以建议自己搭一遍,然后照着正点原子的设置去改。
  2. video timing controller因IP版本不一致而带来的引脚不一致:我的vivado的vtc是6.2版本的,它多了一个sof_state,但经过我的实际测试,它空着不接即可。不会影响现有功能。
  3. 引脚定位不一致:下文我会给出我的xdc代码

代码

这里只提供xdc的代码,其他代码请直接看正点原子的开源代码

开源代码链接及其路径:领航者v2/2_Embedded_System/ZYNQ_SDK_7010/26_ov5640_hdmi

XDC

#----------------------摄像头接口的时钟---------------------------
#72M
create_clock -period 13.888 -name cam_pclk_0 [get_ports cam_pclk_0]
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets cam_pclk_0_IBUF_BUFG]
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets cam_pclk_0_IBUF]

set_property PACKAGE_PIN M17 [get_ports cam_vsync_0]
set_property IOSTANDARD LVCMOS33 [get_ports cam_vsync_0]
set_property PACKAGE_PIN J20 [get_ports cam_pclk_0]
set_property IOSTANDARD LVCMOS33 [get_ports cam_pclk_0]
set_property PACKAGE_PIN G19 [get_ports cam_pwdn_0]
set_property IOSTANDARD LVCMOS33 [get_ports cam_pwdn_0]
set_property PACKAGE_PIN N20 [get_ports cam_href_0]
set_property IOSTANDARD LVCMOS33 [get_ports cam_href_0]
set_property PACKAGE_PIN M18 [get_ports cam_rst_n_0]
set_property IOSTANDARD LVCMOS33 [get_ports cam_rst_n_0]
set_property PACKAGE_PIN H20 [get_ports {cam_data_0[7]}]
set_property PACKAGE_PIN K19 [get_ports {cam_data_0[6]}]
set_property PACKAGE_PIN J19 [get_ports {cam_data_0[5]}]
set_property PACKAGE_PIN L20 [get_ports {cam_data_0[4]}]
set_property PACKAGE_PIN L19 [get_ports {cam_data_0[3]}]
set_property PACKAGE_PIN L17 [get_ports {cam_data_0[2]}]
set_property PACKAGE_PIN L16 [get_ports {cam_data_0[1]}]
set_property PACKAGE_PIN M20 [get_ports {cam_data_0[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {cam_data_0[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {cam_data_0[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {cam_data_0[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {cam_data_0[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {cam_data_0[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {cam_data_0[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {cam_data_0[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {cam_data_0[0]}]
set_property PACKAGE_PIN H16 [get_ports UART_0_0_rxd]
set_property PACKAGE_PIN H17 [get_ports UART_0_0_txd]
set_property IOSTANDARD LVCMOS33 [get_ports UART_0_0_rxd]
set_property IOSTANDARD LVCMOS33 [get_ports UART_0_0_txd]
set_property PACKAGE_PIN B19 [get_ports {TMDS_0_tmds_data_p[2]}]
set_property PACKAGE_PIN C20 [get_ports {TMDS_0_tmds_data_p[1]}]
set_property PACKAGE_PIN D19 [get_ports {TMDS_0_tmds_data_p[0]}]
set_property PACKAGE_PIN F19 [get_ports TMDS_0_tmds_clk_p]

#cam_scl:
set_property -dict {PACKAGE_PIN P18 IOSTANDARD LVCMOS33} [get_ports {emio_sccb_tri_io[0]}]
#cam_sda:
set_property -dict {PACKAGE_PIN M19 IOSTANDARD LVCMOS33} [get_ports {emio_sccb_tri_io[1]}]
set_property PULLUP true [get_ports {emio_sccb_tri_io[1]}]


代码研读

既然是学习,就不能浅尝辄止,下面是一些我学习时的笔记。

API函数:run_vdma_frame_buffer()

这个函数将根据ID配置VDMA的读写路径,ID就是直接上xparameters.h找到你在vivado中配置的VDMA ID即可。

#define XPAR_AXIVDMA_0_DEVICE_ID XPAR_AXI_VDMA_0_DEVICE_ID
参数列表
位置参数含义
1InstancePtr是XAxiVdma数据结构的句柄
2DeviceId当前VDMA的设备ID
3hize帧的水平大小,以像素为单位
4vsize帧的垂直大小。
5buf_base_addrVDMA写入和读取帧的缓冲区地址
6number_frame_count指定中断应该在多少帧之后到来
7enable_frm_cnt_intr置1时启用帧计数中断。
8select可设置读取通道、写入通道或读取和写入通道。
返回值

XST_SUCCESS 和 -XST_FAILURE

本项目设置
run_vdma_frame_buffer(&vdma, VDMA_ID, vd_mode.width, vd_mode.height,
						frame_buffer_addr,0,0,BOTH);

其中,选择关闭帧计数中断,和中断计数,并将通道选择为both,即为读写通道

frame_buffer_adder的计算

这个是重点

unsigned int const frame_buffer_addr = (XPAR_PS7_DDR_0_S_AXI_BASEADDR
										+ 0x1000000);

其中XPAR_PS7_DDR_0_S_AXI_BASEADDR比较好理解,它就是我们在建立BD文件时,为这个VDMA分配的帧缓存空间的起始地址

/* Definitions for peripheral PS7_DDR_0 */
#define XPAR_PS7_DDR_0_S_AXI_BASEADDR 0x00100000
#define XPAR_PS7_DDR_0_S_AXI_HIGHADDR 0x0FFFFFFF

而加上0x1000000是为了给ps端运行留一些内存,让他使用的。

API函数:DisplayInitialize()

这个是用来配置我们放置在BD中的动态时钟的,深入研究发现它很厉害,能根据“视频格式”生成对应的时钟。
它能够通过当前的video timing contraller 的ID获知,当前使用的是什么格式的视频流,进而查表后输出相应的时钟频率。相当好用

DisplayInitialize(&dispCtrl, DISP_VTC_ID, DYNCLK_BASEADDR);

第二个参数就是当前的video timing contraller 的ID,然后他会把得到的视频格式信息写入dispCtrl结构体中,给后续流程使用。

typedef struct {
		u32 	 dynClkAddr;/*Physical Base address of the dynclk core*/
		XVtc vtc;		 	/*VTC driver struct*/
		VideoMode vMode; 	/*Current Video mode*/
		double pxlFreq;		/* Frequency of clock currently being generated */
		DisplayState state; /* Indicates if the Display is currently running */
} DisplayCtrl;
typedef struct {
	char label[64]; /* Label describing the resolution */
	u32 width; /*Width of the active video frame*/
	u32 height; /*Height of the active video frame*/
	u32 hps; /*Start time of Horizontal sync pulse, in pixel clocks (active width + H. front porch)*/
	u32 hpe; /*End time of Horizontal sync pulse, in pixel clocks (active width + H. front porch + H. sync width)*/
	u32 hmax; /*Total number of pixel clocks per line (active width + H. front porch + H. sync width + H. back porch) */
	u32 hpol; /*hsync pulse polarity*/
	u32 vps; /*Start time of Vertical sync pulse, in lines (active height + V. front porch)*/
	u32 vpe; /*End time of Vertical sync pulse, in lines (active height + V. front porch + V. sync width)*/
	u32 vmax; /*Total number of lines per frame (active height + V. front porch + V. sync width + V. back porch) */
	u32 vpol; /*vsync pulse polarity*/
	double freq; /*Pixel Clock frequency*/
} VideoMode;

static const VideoMode VMODE_480x272 = {
	.label = "480x272@60Hz",
	.width = 480,
	.height = 272,
	.hps = 482,
	.hpe = 523,
	.hmax = 525,
	.hpol = 0,
	.vps = 274,
	.vpe = 284,
	.vmax = 286,
	.vpol = 0,
	.freq = 9
};

static const VideoMode VMODE_640x480 = {
	.label = "640x480@60Hz",
	.width = 640,
	.height = 480,
	.hps = 656,
	.hpe = 752,
	.hmax = 799,
	.hpol = 0,
	.vps = 490,
	.vpe = 492,
	.vmax = 524,
	.vpol = 0,
	.freq = 25.12
};

没写完,锻炼完回来再写

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/588300.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

1991-2022年上市公司短贷长投/短债长用/投融资期限错配(包含原始数据及Stata代码)

01、数据简介 上市公司在投融资过程中,可能会涉及到投融资期限错配、短债长用和短贷长投等问题 投融资期限错配是指企业的资产与债务期限不匹配,主要表现为“短存长贷”,即资金来源短期化、资金运用长期化。当风险缓释的期限比当前的风险暴…

Elasticsearch:理解近似最近邻 (ANN) 算法

作者:来自 Elastic Elastic Platform Team 如果你是在互联网出现之前长大的,你会记得找到新喜好并不总是那么容易。我们是在无意中听到收音机里的新乐队时发现他们的,是因为忘了换频道偶然看到一个新电视节目的,也是几乎完全依据游…

本地搭建llama大模型及对话UI

环境说明:MBP 2023 M2Pro芯片 用到的工具/组件/技术:ollama、llama3:8b、docker、open-webui 1.下载ollama ollama官网下载地址:https://ollama.com/download 到ollama官网地址下载对应操作系统版本的ollama平台,按照安装指引…

unity制作app(2)--主界面

1.先跳转过来,做一个空壳!新增场景main为4号场景! 2.登录成功跳转到四号场景! 2.在main场景中新建canvas,不同的状态计划用不同的panel来设计! 增加canvas和底图image 3.突然输不出来中文了,浪…

区块链 | IPFS:CID

🦊原文:Anatomy of a CID 🦊写在前面:本文属于搬运博客,自己留存学习。 1 CID 在分布式网络中与其他节点交换数据时,我们依赖于内容寻址(而不是中心化网络的位置寻址)来安全地定位…

stm32单片机开发四、USART

串口的空闲状态时高电平,起始位是低电平,来打破空闲状态的高电平 必须要有停止位,停止位一般为一位高电平 串口常说的数据为8N1,其实就是8个数据位(固定的),N就是none,也就是0个校验…

审计师能力与专长数据集(2014-2022年)

01、数据介绍 审计师是专门从事审计工作的人员,他们对企业、政府机关、金融机构等组织进行独立的、客观的、合法的审计,以评估这些组织的财务状况、经营绩效和风险水平。审计师通过收集和评估证据,以确定被审计单位的财务报表是否公允、合法…

[数据结构]———交换排序

目录 1.交换排序 第一个定义了一个名为Swap的函数 第二个三数取中 2.冒泡排序 代码解析 冒泡排序的特性总结: 3.快速排序 1. hoare版本 2. 挖坑法 代码解析 3. 前后指针版本 代码解析 1.交换排序 基本思想:所谓交换,就是根据序列中两…

MyBatis-plus笔记——条件构造器和常用接口

wapper介绍 Wapper:条件构造抽象类 AbstractWapper:用于查询条件封装,生成 sql 的 where 条件 QueryWrapper:查询条件封装UpdateWrapper:Update 条件封装AbstractLambdaWrapper:使用Lambda语法 LambdaQuery…

五一假期Llama 3之魔改不完全攻略(Part 2)

2024年4月18日,Meta AI 正式宣布推出 Llama 3,这标志着开源大型语言模型(LLM)领域的又一重大进步。如同一颗重磅炸弹, Llama 3 以其卓越的性能和广泛的应用前景,预示着 AI 技术的新时代。 目前开源的是Lla…

Agent AI智能体:机器学习与自我优化的奇妙之旅

文章目录 📑前言一、Agent AI智能体的基本概念二、Agent AI智能体的技术进步2.1 机器学习技术2.2 自适应技术2.3 分布式计算与云计算 三、Agent AI智能体的知识积累3.1 知识图谱3.2 迁移学习 四、Agent AI智能体的挑战与机遇4.1 挑战4.2 机遇 小结 📑前言…

ASP.NET网络商店设计与实现

摘 要 本文首先系统地研究了开发电子商务网站的背景和意义,分析了当今B2C电子商务交易的网站特点和共性,从而得出设计本网站的思路和方法。接着介绍了实现系统开发的ASP.NET和IIS5.0环境,数据库用ACCESS实现。同时简要介绍了以上工具的功能…

手拉手springboot整合kafka

前期准备安装kafka 启动Kafka本地环境需Java 8以上 Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者在网站中的所有动作流数据。 Kafka启动方式有Zookeeper和Kraft,两种方式只能选择其中一种启动,不能同时使用。 Kafka下载…

状态模式

文章目录 1.UML类图2.状态基类3.状态实现类3.状态机管理类使用示例 1.UML类图 2.状态基类 public abstract class State {public string? Name { get; set; }public StateMachine? StateMachine {get; set;}public abstract void Exit();public abstract void Enter(); }3.…

Devops部署maven项目

这里讲下应用k8s集群devops持续集成部署maven项目的流程。 failed to verify certificate: x509: certificate signed by unknown authority 今天在执行kubectl get nodes的时候报的证书验证问题,看了一圈首次搭建k8s的都是高频出现的问题。 couldn’t get curren…

输入N,从1~N中挑出若干对数字,比如(a,b),(c,d)

题目: 输入N,从1~N中挑出若干对数字,比如(a,b),(c,d) 规定这个数对的value为两数之和,比如(a,b)的value为ab 现在从1~N中挑出若干个数对,他们满足: 每个数字只能被挑出一次 每个数对的value都不相等 每个数对的value都小于等于N 求:对于给定的N,能挑出这样的数对的最大个数max …

2024年Q1葡萄酒行业线上电商(京东天猫淘宝)销售排行榜

五一聚餐不可缺少饮品——葡萄酒。鲸参谋监测的线上电商平台(某东)Q1季度葡萄酒行业销售数据已揭晓! 从鲸参谋的数据中,我们可以明显看到今年Q1季度在线上电商平台(某东)葡萄酒行业的销售情况呈现出积极的…

【C++】STL使用详解

文章目录 前言1. string类1.1 string类对象的常见构造1.2 string类对象的容量操作1.3 string类对象的访问及遍历操作1.4 string类对象的修改操作1.5 string类非成员函数 2. vector2.1 vector的介绍2.2 vector的使用2.3 vector的迭代器2.4 vector空间容量操作2.5 vector增删查改…

笨蛋学C++之 C++连接数据库

笨蛋学C 之 VS2019使用C连接数据库 创建数据库SQL语句VS2019选择空项目,点击下一步创建输入项目名称,点击创建创建成功点击新建项创建源文件因为mysql是64位,此时的c项目是86位,所以这里需要将项目修改为x64位点击项目 -> 0501…

基于Python的人脸识别系统设计与实现(论文+源码)_kaic

基于Python的人脸识别系统设计与实现 摘 要 随着人工智能的发展,人脸识别系统在我们的生活中越来越被广泛应用。人脸识别系统是指能够从数字图像或视频源中识别人的技术。人脸识别系统可以通过多种方法工作,但是,它们通常是通过将给定图像中的面部特征与…