基于 OV2640 的以太网 RGMII 图像传输系统设计

文章目录

  • 前言
  • 一、UDP 协议的特点
  • 二、图像数据编码原理
  • 三、系统总体设计
  • 四、图像编码模块介绍
    • 4.1、图像编码模块作用
    • 4.2、图像编码模块功能实现
    • 4.3、仿真
  • 五、其他涉及模块说明
  • 六、顶层模块
  • 七、下载与验证


前言

本节主要讲述了一种对数据以行为单位的编码方法。该方法采用摄像头采集数据后经由 FPGA 的 RGMII 接口通过 UDP 协议实现以太网图像传输。以该方法进行 UDP 协议下的以太网图像传输,可以有效缓解 UDP 协议的差错控制缺陷带来的传输质量不佳问题。


提示:任何文章不要过度深思!万事万物都经不起审视,因为世上没有同样的成长环境,也没有同样的认知水平,更「没有适用于所有人的解决方案」 ;不要急着评判文章列出的观点,只需代入其中,适度审视一番自己即可,能「跳脱出来从外人的角度看看现在的自己处在什么样的阶段」才不为俗人 。怎么想、怎么做,全在乎自己「不断实践中寻找适合自己的大道」

一、UDP 协议的特点

我们通过以太网进行数据传输时,通常对于一些对数据正确性要求较低
(允许少量丢失)但是不能有较大时延的场景,都会使用 UDP 协议。UDP 协议是传输层的一种协议,该协议具有以下特点:

  1. 提供不可靠传输。在进行数据传输时 UDP 提供尽最大努力的交付,但不保证可靠交付。
  2. 高效而无连接性。UDP 协议在传输数据前不建立连接,不对数据报进行检查与修改,无须等待对方的应答,所以会出现分组丢失、重复、乱序等问题,如果因为网络原因没有传送到对端,UDP 也不会给应用层返回错误信息。但正因为 UDP 在进行发送时不需要建立连接,所以其在网络开销较小的同时工作时效也相当高。
  3. UDP 没有拥塞控制。应用层能够更好的控制要发送的数据和发送时间,网络中的拥塞控制也不会影响主机的发送速率,因此UDP协议常常被用于某些对数据发送速率有一定要求,能容忍一些数据的丢失,但是不能允许有较大的时延的场景,如直播,视频等。
  4. UDP 在现场测控领域,往往面向的是分布化的控制器、监测器等应用。现场测控领域的电磁环境往往较为复杂,基于此,现场通信中,若某一应用要将一组数据传送给网络中的另一个节点,可由 UDP 进程将数据加上报头后传送给 IP 进程。由于 UDP 协议省去了建立连接和拆除连接的过程,取消了重发检验机制,所以能够达到较高的通信速率。

正因为 UDP 协议有如上种种优点,所以可以对 UDP 协议图像传输的策略进行改进,而降低干扰的影响后,UDP 协议仍然可以作为图像传输的一种优质
方案。

二、图像数据编码原理

我们前面说过:以太网图像数据的传输通常采用 UDP 协议,图像数据在传输时一旦受到外界干扰发生数据丢失,而数据的丢失会导致图像发生断层,割裂,压缩等现象。
正因为如此,我们可以进行如下有针对性的改进后,仍保留使用 UDP 协议:如果我们对图像数据进行处理,将摄像头采集到的图像数据按照一定的编号方式例如以行为单位编号后,再通过 UDP 协议经由以太网传输到电脑,电脑接收FPGA 发送的图像数据解析后按照编号将相应的图像内容绘制到电脑显示屏的对应位置上,就能有效解决该问题。
经过该种编码方法改进,当数据在通过 UDP 协议传输的时候,理论上即使发生了少量数据丢失也不会出现断层割裂等效果。而对于图像传输显示这类场景,对于图像数据的准确性要求较低,即使一幅图像中有一两行数据的丢失,只要不是每幅图像都有该丢失情况,在每秒几十上百帧的刷新率下,其影响也极小。为了让上述理论能够更加加通俗易懂,我们结合图形,来对该理论进行讲解。
本次设计原理如图所示:
在这里插入图片描述
左边第一张为图像的写入过程,图像数据从左至右被依次写入。
第二张图为正常写入后所应展现出的画面,假设被标绿线的行在传输过程中丢失了,在未对行号进行编码的情况下,将会得到第三张图中被压缩的结果,而后续如果仍有图像传输过来,甚至可能出现两张图像重叠的情况,会影响后续图像数据的显示效果。
如果我们对每行图像数据进行编号,即使数据在传输过程中有部分行的数据丢失了,但因为序号的存在,它们仍会排列在自己所应处的位置。
举例来说:上图中,假设绿色行发生丢失,数据在显示屏上的显示画面如第四张图,被丢失的行由于没有数据,会显示黑色,即使数据丢失,图像也不会发生压缩等现象,只会在当前帧有影响,不会影响后续帧的图像。在每秒几十帧的刷新率下,一两行数据的丢失对人眼而言甚至无法识别到,或者只是看到黑线一闪而过。
在理解了本次设计最终目的的实现原理后,接下来可以开始进行工程的设
计。

三、系统总体设计

我们可以结合前面开发的内容,作如下设计。本次本次板级验证我们将在开发板上结合前面章节学习过的以太网传图工程对设计模块进行验证。
在这里插入图片描述
结合板级验证的硬件搭建环境,本章节的原理作如下对应与深化讲解:

  1. 整个系统在开始工作前,首先按照初始化 table 表对摄像头进行初始化参考基于 OV2640 的图像采集显示系统(camera_init 摄像头初始化模块)
  2. 然后对以太网芯片初始化(此模块可以不用),可参考以太网初始化设计(MDIO 控制器)
  3. 随 后 摄 像 头 将 采 集 到 的 数 据 经 由 DVP 接 口 输 送 给Camera_ETH_Formator模块,也就是本次设计的模块,该模块会根据输入数据行场同步信号的高低电平,以行为单位,对其进行编码。
  4. 随后数据进入一个双口 FIFO 中,当 FIFO 中的值足够进行一次以太网数据传输时,数据就会被发送模块读出。使用 UDP 协议将读出的数据经过 crc 校验后,经由以太网发送到 PC 机,参考千兆以太网传输层 UDP 协议原理与 FPGA 实现(UDP发送)、RGMII 与 GMII 转换电路设计
  5. PC 端使用显示软件接收 FPGA发送的包含行编号的图像数据,解析后还原为图像内容绘制在PC 机显示屏上。
    根据前面学习内容的基础,在本章,我们着重讲解图像编码模块的作用,

以上处顶层模块与Camera_ETH_Formator模块外其他模块均在相关文章中讲述,可以参考我的相关文章。

四、图像编码模块介绍

4.1、图像编码模块作用

根据前面介绍的设计思想,本次模块设计的目的是实现对图像数据以行为单位进行编号。如果实现数据以行为单位编号,就需要知道当前输入的数据位
于每帧图像数据的哪一行。对此,我们可以通过计数行场同步信号实现。
模块 Camera_ETH_Formator 在整个系统内,可以起到防止在图像显示的过
程中由于某一行数据的丢失,导致的图像压缩断层现象发生的作用。在加入了该模块后,数据会按照其排列序号一行行进行排列,即使有一行或多行数据丢失,其余行数据也会排列在自己所应处的位置。
综合以上信息,设计模块 Camera_ETH_Formator 的结构如图 :
在这里插入图片描述
其中各个信号的含义如表所示:
在这里插入图片描述
当 HREF由低电平转为高电平时,DATA开始输入到图像数据编码模块,当
HREF 从高电平转为低电平时代表一行的数据输出完成,当模块中的数据处理完成后便会产生 wrreq 信号,并输出 8 位的 wrdata 数据。
我们以 1280*720 的显示屏为例,在摄像头将采集到的 RGB565 格式数据通过以太网发送给 PC 的显示屏显示的过程中,每一行有两倍 1280 个字节即 2560字节有效数据。依照前文我们介绍的设计思想:为了让部分数据即使在丢失的情况下其余行数据也能显示在自己应处的位置,我们可以在每一行的数据前加上 2 个字节的行号。也就是说,以太网每一帧,需要发送一行的数据外加两个字节的行号。

4.2、图像编码模块功能实现

为了方便理解和设计,我们绘制了本次模块设计各个信号之间的时序图,如图图像编码模块时序图:
在这里插入图片描述
上图中:href_r1 和 href_r2 为对摄像头行同步 HREF 信号寄存后得到的信号,data_tmp 为 24 位的寄存器,用来完成对数据的移位转换。
如:时序图中 C0 时刻,当 HREF 出现上升沿时,代表数据开始输入。此时
我们可以用 HREF 与 href_r1 位拼接后的值表示,当{href_r1,HREF }的值为2’b01 时,HREF 的电平由低到高,数据开始输入;当{ href_r1,HREF }的值为2’b10 时,HREF 的电平由高到低,一行数据输入完毕,数据停止输入。
本次模块设计的目的是以行为单位,对数据进行编号,根据 HREF 的电平变化,我们可以利用计数器对行信号进行下降沿次数的累加生成行号,该部分代码实现如下:

//---------------------------------------//VSYNC为高电平(有效)时,每当HREF1拉低时自加1,为记录行号always@(posedge PCLK or negedge Rst_n)if(!Rst_n)Vcnt <= 0;else if(!VSYNC)Vcnt <= 0;else if({href_r1,HREF} == 2'b10)Vcnt <= Vcnt + 1'd1;//---------------------------------------	

代码中:Vcnt 为行号计数器,每当 HREF 电平状态由高变低时,代表一行数据输出完毕,此时我们只需使计数器自加一即可,当VSYNC信号为低电平,即代表一幅图像数据输入完成,此时将计数器清零。完成了行号的产生,接下来就是将行号写入数据中。

如时序图中所示,C0 处检测到 HREF 信号的上升沿,由于该上升沿在时钟上升沿之后才到来,所以实质上该信号是在下一个时钟上升沿到来时才被采集到。该信号被采集后,随即将行号写入 data_tmp 寄存器中。当 2 字节的行号输出完成后,再开始输出图像数据,相应的代码如下:

//---------------------------------------//对HREF进行计数,用于判断奇偶,对data_tmp进行数据拼接reg [11:0]HREF_CNT;always@(posedge PCLK or negedge Rst_n)if(!Rst_n)	HREF_CNT <= 0;else if({href_r1,HREF} == 2'b01)HREF_CNT <= HREF_CNT + 1;else if(href_r1)HREF_CNT <= HREF_CNT + 1;else if(!href_r1)HREF_CNT <= 0;else HREF_CNT <= HREF_CNT;//---------------------------------------//---------------------------------------//HREF1上升沿时移位传输数据always@(posedge PCLK or negedge Rst_n)if(!Rst_n)data_tmp <= 0;else if({href_r1,HREF} == 2'b01)data_tmp <= {Vcnt[7:0],Vcnt[15:8],DATA};else if(HREF_CNT[0] == 1)data_tmp <= {data_tmp[15:8],DATA,data_tmp[7:0]};else if(HREF_CNT[0

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

树莓派Pi4B简介

树莓派是什么&#xff1f;Raspberry Pi(中文名为“树莓派”,简写为RPi&#xff0c;或者RasPi/RPi)是为学生计算机编程教育而设计&#xff0c;只有信用卡大小的卡片式电脑&#xff0c;其系统基于Linux。 树莓派4B与树莓派3B/3B参数对比&#xff1a; 具体的实物图如下&#xff1a…

PDF控件Spire.PDF for .NET【安全】演示:在 PDF 中添加或删除数字签名

随着 PDF 文档在商业中越来越流行&#xff0c;确保其真实性已成为一个关键问题。使用基于证书的签名对 PDF 进行签名可以保护内容&#xff0c;还可以让其他人知道谁签署或批准了该文档。在本文中&#xff0c;您将了解如何使用不可见或可见签名对 PDF 进行数字签名&#xff0c;以…

2023年教程汇总 | 《小杜的生信笔记》

2023年总结 2023年即将结束&#xff0c;我们即将迎来2024年。2023年&#xff0c;我们做了什么呢&#xff1f;&#xff1f;这个是个值得深思的问题…? 12月份是个快乐且痛苦时间节点。前一段时间&#xff0c;单位需要提交2023年工作总结&#xff0c;真的是憋了好久才可以下笔…

国产编程语言MoonBit添加问号操作符

MoonBit更新 01. 添加内置类型 Result enum Result[T, E] {Ok(T)Err(E) }02. 添加问号操作符 新增了问号操作符&#xff0c;用于简化错误处理&#xff1a; fn may_fail() -> Option[Int] { ... }fn compose_may_fail() -> Option[String] {let x may_fail()?let y …

ioDraw AI:思维导图、流程图、序列图、类图、饼图,一应俱全

前言 在信息爆炸的时代&#xff0c;我们每天接收着大量的信息&#xff0c;如何高效地整理和呈现这些信息成为了一项重要的挑战。思维导图作为一种可视化思维工具&#xff0c;能够帮助我们快速构建和整理复杂的信息结构&#xff0c;便于我们理解和记忆。ioDraw AI绘图工具正是基…

RTOS_WDS

2023/12/25重启韦东山老师RTO 韦东山freeRTOS快速入门视频教程 P2 2-1堆的概念 堆 char heap_buf[1024]; int pos 0;void *my_malloc(int size) {int old_pos pos;pos size;return &heap_buf[old_pos]; }void my_free(void *buf) {/* err */ }int main(void) {char ch…

react+koa全栈开发 以及 部署流程

前端开发后端开发部署 前端开发 前端使用react、sass、TS、vite、pnpm进行开发&#xff0c;太详细的这里就不展开说了项目创建可以参考我的另外一篇文章 优雅地创建一个前端项目 后端开发 后端使用node&#xff0c;使用koa框架进行开发&#xff0c;数据库我使用的是一个mys…

Android studio 使用greenDao根据实体类生成dao类

1.遇到的问题 使用android studio根据实体类生成dao其实也很简单&#xff0c;你只要实现 Parcelable Entity public class ConfigDataModel implements Parcelable {Id(autoincrement true)private Long id null; } 2.使用自带的方法生成 使用build-->make Project生成 …

学Java的第二天

一、常量 1.值不可以变化的量。 2. 分类&#xff1a; 字符串常量 用双引号括起来的多个字符&#xff0c;可以包含 0、1 或多个&#xff0c;例如 "a" 、 "abc" 、 " 中国 " 整数常量&#xff0c;例如&#xff1a; -10 、 0 、 88 小数常量&…

在x64上构建智能家居(home assistant) (六) 安装Node-RED Companion Integration

点击HACS 搜索node-red 右侧单击后点击安装 安装完成后, 选设备

分别使用OVP-UVP和OFP-UFP算法以及AFD检测算法实现反孤岛检测simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 OVP-UVP算法 4.2 OFP-UFP算法 4.3 AFD检测算法 5.完整工程文件 1.课题概述 分别使用OVP-UVP和OFP-UFP算法以及AFD检测算法实现反孤岛检测simulink建模与仿真。 2.系统仿真结果 3.核心程序与模型…

Redis案例实战之Bitmap、Hyperloglog、GEO

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码、Kafka原理、分布式技术原理、数据库技术&#x1f525;如果感觉博主的文章还不错的…

【如何破坏单例模式(详解)】

✅如何破坏单例模式 &#x1f4a1;典型解析✅拓展知识仓✅反射破坏单例✅反序列化破坏单例✅ObjectlnputStream ✅总结✅如何避免单例被破坏✅ 避免反射破坏单例✅ 避免反序列化破坏单例 &#x1f4a1;典型解析 单例模式主要是通过把一个类的构造方法私有化&#xff0c;来避免重…

uniapp框架——vue3+uniFilePicker+fastapi实现文件上传(搭建ai项目第二步)

文章目录 ⭐前言&#x1f496; 小程序系列文章 ⭐uni-file-picker 组件&#x1f496; 绑定事件&#x1f496; uploadFile api&#x1f496; 自定义上传 ⭐后端fastapi定义上传接口⭐uniapp开启本地请求代理devServer⭐前后端联调⭐总结⭐结束 ⭐前言 大家好&#xff0c;我是ym…

数据库原理及应用·关系数据库标准语言SQL

4.1 SQL概述 4.1.1 SQL的产生和发展 1.产生 1974年&#xff0c;SQL语言的雏形最早由美国IBM公司的Raymond F. Boyce和Donald D. Chamberlin提出 1975-1979年&#xff0c;在System R上首次实现&#xff0c;由IBM的San Jose研究室研制&#xff0c;称为SEQUEL 2.发展 1986年推…

猫头虎分享2023年12月17日博客之星候选--城市赛道博主文章数据

猫头虎分享2023年12月17日博客之星候选–城市赛道博主文章数据 博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开…

udp广播的例子

以下是一个使用C语言描述广播发送和接收的简单示例&#xff1a; 发送端&#xff08;广播发送&#xff09;&#xff1a; #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> #inclu…

Linux gdisk创建GPT分区

gdisk命令工具默认将磁盘划分为GPT格式的分区&#xff1a; lsblk 查看分区 创建GPT格式的分区&#xff1a; 列出磁盘分区表&#xff1a; fdisk -l 有一个新的磁盘sdc 下面将sdc进行GPT分区 输入gdisk /dev/sdc 输入&#xff1f;查看帮助文档&#xff1a; 输入n 创建新的分…

Java@RequestParam注解和@RequestBody注解接收参数

目录 Java后端接收数据 第一章、后端不写任何注解情况下接收参数1.1&#xff09;后端不写注解postman发出get请求1.2&#xff09;后端不写注解postman发出post请求 第二章、后端写RequestParam注解接收参数2.1&#xff09;postman发出post请求2.2&#xff09;postman发出get请求…

MySQL 中的 INSERT 是怎么加锁的?

在之前的博客中&#xff0c;我写了一系列的文章&#xff0c;比较系统的学习了 MySQL 的事务、隔离级别、加锁流程以及死锁&#xff0c;我自认为对常见 SQL 语句的加锁原理已经掌握的足够了&#xff0c;但看到热心网友在评论中提出的一个问题&#xff0c;我还是彻底被问蒙了。他…