5)关注
正点原子公众号,获取最新资料更新
第四十七章 基于OV5640的以太网传输视频实验
在 “基于OV7725的以太网视频传输实验” 中, 我们成功地在上位机显示软件上实时显示出了摄像头采集的图像。 本章我们将使用FPGA开发板实现对OV5640的数字图像采集, 并通过开发板上的以太网接口发送给上位机实时显示。
本章包括以下几个部分:
47.1
以太网视频传输简介
47.2
实验任务
47.3
硬件设计
47.4
程序设计
47.5
下载验证
47.1
以太网视频传输简介
我们在“基于OV7725的以太网视频传输实验” 中对视频传输方案的选择以及UDP传输视频的处理方法等内容作了详细的介绍, 如果大家对这部分内容不是很了解的话, 请参考“基于OV7725的以太网视频传输实验” 中的以太网视频传输简介部分。
47.2
实验任务
本节实验任务是使用FPGA开发板及OV5640摄像头实现图像采集, 并通过开发板上的以太网接口发送给上位机实时显示。
47.3
硬件设计
摄像头扩展接口原理图及OV5640模块说明与“OV5640摄像头VGA显示实验” 完全相同, 请参考“OV5640摄像头VGA显示实验” 硬件设计部分。 以太网接口部分的硬件设计请参考“以太网通信实验” 中的硬件设计部分。
由于OV5640、 以太网接口和SDRAM引脚数目较多且在前面相应的章节中已经给出它们的管脚列表, 这里不再列出管脚分配。
47.4
程序设计
图 47.4.1是根据本章实验任务画出的系统框图。 对比“基于OV7725的以太网视频传输实验” 的系统框图可以发现, 我们只是把外设OV7725模块替换成了OV5640模块, 其余模块基本相同(IIC配置模块有差异) 。 PLL时钟模块用于为IIC驱动模块和SDRAM控制模块提供驱动时钟,
而UDP模块的驱动时钟是由开发板上的PHY芯片提供。 I2C驱动模块和I2C配置模块用于初始化OV5640图像传感器; 摄像头采集模块负责采集摄像头图像数据, 并且把图像数据写入SDRAM读写控制模块中; SDRAM读写控制模块负责将用户数据写入和读出片外SDRAM存储器; 图像数据封
装模块从SDRAM读写控制模块中读出数据, 封装成以太网发送模块的数据格式, 包括添加图像的帧头; 以太网发送模块发送封装后的图像数据, 其发送的CRC校验值由CRC32校验模块负责计算。
OV5640的以太网视频传输系统框图如下图所示:
图 47.4.1 基于OV5640摄像头RGB TFT-LCD显示系统框图
顶层模块的原理图如下图所示:
图 47.4.2 顶层模块原理图
由上图可知, FPGA顶层模块(ov5640_rgb565_640x480_udp_pc) 例化了以下七个模块:PLL时钟模块(pll_clk) 、 I2C驱动模块(i2c_dri) 、 I2C配置模块(i2c_ov5640_rgb565_cfg)、摄像头图像采集模块(cmos_capture_data) 、 SDRAM读写控制模块(sdram_top) 、 图像数据
封装模块(img_data_pkt) 和UDP模块(udp) 。PLL时钟模块(pll_clk) : PLL时钟模块通过调用锁相环(PLL) IP核来实现, 总共输出3个时钟, 频率分别为100Mhz、 100Mhz(SDRAM相位偏移时钟)和25Mhz时钟。 100Mhz时钟和100Mhz相位偏移时钟作为SDRAM读写控制模块的驱动时钟, 25Mhz时钟作为I2C驱动模块的驱动时钟。I2C驱动模块(i2c_dri) : I2C驱动模块负责驱动OV5640 SCCB接口总线, 用户可根据该模块提供的用户接口可以很方便的对OV5640的寄存器进行配置, 该模块和“EEPROM读写实验” 章节中用到的I2C驱动模块为同一个模块, 有关该模块的详细介绍请大家参考“EEPROM读写实验”章节。I2C配置模块(i2c_ov5640_rgb565_cfg) : I2C配置模块的驱动时钟是由I2C驱动模块输出的时钟提供的, 这样方便了I2C驱动模块和I2C配置模块之间的数据交互。 该模块寄存需要配置的寄存器地址、 数据以及控制初始化的开始与结束, 同时该模块输出OV5640的寄存器地址和数据以及控制I2C驱动模块开始执行的控制信号, 直接连接到I2C驱动模块的用户接口, 从而完成对OV5640传感器的初始化。 有关该模块的详细介绍请大家参考“OV5640摄像头VGA显示实验”章节。
摄像头图像采集模块(cmos_capture_data) : 摄像头采集模块在像素时钟的驱动下将传感器输出的场同步信号、行同步信号以及8位数据转换成SDRAM读写控制模块的写使能信号和16位写数据信号, 完成对OV5640传感器图像的采集。 OV7725和OV5640图像输出时序非常相似, 有
关该模块的详细介绍请大家参考“OV7725摄像头VGA显示实验” 章节。SDRAM读写控制模块(sdram_top) : SDRAM读写控制器模块负责驱动SDRAM片外存储器, 缓存图像传感器输出的图像数据。 该模块将SDRAM复杂的读写操作封装成类似FIFO的用户接口,
非常方便用户的使用。图像数据封装模块(img_data_pkt) : 图像数据封装模块负责从SDRAM中读取16位的图像数据, 并转换成以太网发送模块方便调用的32位数据, 以及添加图像数据的帧头。 该模块控制着以太网发送模块发送的字节数,单次发送一行图像数据,模块内部例化了一个同步FIFO模块,用于缓存待发送的图像数据。有关该模块的详细介绍请大家参考“基于OV7725的以太网视频传输实验” 章节。UDP模块(udp) : UDP模块实现以太网通信的收发功能, 该模块内部例化了以太网接收模块(ip_receive) 、 以太网发送模块(ip_send) 和CRC32校验模块(crc32_d4) 。 其中以太网的接收功能并没有用到。 有关该模块的详细介绍请大家参考“以太网通信实验” 章节。
顶层模块部分代码如下:
55 //parameter define
56 parameter SLAVE_ADDR = 7'h3c ; //OV5640的器件地址7'h3c
57 parameter BIT_CTRL = 1'b1 ; //OV5640的字节地址为16位 0:8位 1:16位
58 parameter CLK_FREQ = 26'd25_000_000; //i2c_dri模块的驱动时钟频率 25MHz
59 parameter I2C_FREQ = 18'd250_000 ; //I2C的SCL时钟频率,不超过400KHz
60 parameter CMOS_H_PIXEL = 24'd640 ; //CMOS水平方向像素个数,用于设置SDRAM缓存大小
61 parameter CMOS_V_PIXEL = 24'd480 ; //CMOS垂直方向像素个数,用于设置SDRAM缓存大小
62
63 //开发板MAC地址 00-11-22-33-44-55
64 parameter BOARD_MAC = 48'h00_11_22_33_44_55;
65 //开发板IP地址 192.168.1.123
66 parameter BOARD_IP = {8'd192,8'd168,8'd1,8'd123};
67 //目的MAC地址 ff_ff_ff_ff_ff_ff
68 parameter DES_MAC = 48'hff_ff_ff_ff_ff_ff;
69 //目的IP地址 192.168.1.102
70 parameter DES_IP = {8'd192,8'd168,8'd1,8'd102};
代码较长, 省略部分代码……
216
//图像数据封装模块
217 img_data_pkt
218 #(
219 .CMOS_H_PIXEL (CMOS_H_PIXEL),
220 .CMOS_V_PIXEL (CMOS_V_PIXEL)
221 )
222 u_img_data_pkt(
223 .clk (eth_tx_clk),
224 .rst_n (rst_n & sys_init_done),
225 .img_data (rd_data),
226 .udp_tx_req (udp_tx_req),
227 .udp_tx_done (udp_tx_done),
228 .img_req (rd_en),
229 .udp_tx_start_en (tx_start_en),
230 .udp_tx_data (tx_data),
231 .udp_tx_byte_num (tx_byte_num)
232 );
233
234
//UDP模块
235 udp
236 #(
237 .BOARD_MAC (BOARD_MAC),
//参数例化
238 .BOARD_IP (BOARD_IP ),
239 .DES_MAC (DES_MAC ),
240 .DES_IP (DES_IP )
241 )
242 u_udp(
243 .eth_rx_clk (eth_rx_clk ),
244 .rst_n (rst_n ),
245 .eth_rxdv (eth_rxdv ),
246 .eth_rx_data (eth_rx_data ),
247 .eth_tx_clk (eth_tx_clk ),
248 .tx_start_en (tx_start_en ),
249 .tx_data (tx_data ),
250 .tx_byte_num (tx_byte_num ),
251 .tx_done (udp_tx_done ),
252 .tx_req (udp_tx_req ),
253 .rec_pkt_done (),
254 .rec_en (),
255 .rec_data (),
256 .rec_byte_num (),
257 .eth_tx_en (eth_tx_en ),
258 .eth_tx_data (eth_tx_data ),
259 .eth_rst_n (eth_rst_n )
260 );
261
262
endmodule
在代码的第56行定义了OV5640的器件地址, 其器件地址为7’ h3c; 第57行定义了寄存器地址的位宽, BIT_CTRL=0表示地址位宽为8位, BIT_CTRL=1表示地址位宽为16位。 因为OV5640的地址位宽为16位, 所以BIT_CTRL设置为1。 第60行和第61行分别定义了CMOS输出的水平像素个
数和垂直像素个数, 在这里这两个参数用于设置在SDRAM中开辟的缓存大小、 配置OV5640的图像分辨率以及控制图像数据封装模块内部的参数。 由于上位机按照固定分辨率640*480来解析图像数据, 因此CMOS_H_PIXEL=640, CMOS_H_PIXEL=480。
在代码的第64至第70行定义了四个参量: 开发板MAC地址BOARD_MAC, 开发板IP地址BOARD_IP, 目的MAC地址DES_MAC(这里指PC MAC地址) , 目的IP地址DES_IP(PC IP地址) 。开发板的MAC地址和IP地址是我们随意定义的, 只要不和目的MAC地址和目的IP地址一样就可以,
否则会产生地址冲突。 目的MAC地址这里写的是公共MAC地址(48'hff_ff_ff_ff_ff_ff) , 也可以修改成电脑网口的MAC地址, DES_IP是对应电脑以太网的IP地址, 这里定义的四个参数是向下传递的,需要修改MAC地址或者IP地址时直接在这里修改即可,而不用在udp模块里面修改。
在代码的第229行至第231行代码中,打包发送模块输出的udp开始发送信号(tx_start_en)、tx_data(发送的数据) 和tx_byte_num(发送的字节数) 连接至udp模块的以太网发送端口,从而控制以太网发送模块的开始发送信号、 发送字节数以及发送的数据。
图像数据封装模块负责从SDRAM中读取16位的图像数据, 并转换成以太网发送模块方便调用的32位数据, 以及添加图像数据的帧头。 图像数据封装模块在“基于OV7725的以太网视频传输实验”章节中程序设计部分有着详细的介绍,如果大家对此模块不是很了解的话,请参考“基
于OV7725的以太网视频传输实验” 章节。
47.5
下载验证
首 先 我 们 打 开 OV5640 的 以 太 网 视 频 传 输 实 验 工 程 , 在 工 程 所 在 的 路 径 下 打 开ov5640_rgb565_640x480_udp_pc/par 文 件 夹 , 在 里 面 找 到“ov5640_rgb565_640x480_udp_pc.qpf” 并双击打开。 注意工程所在的路径名只能由字母、 数
字以及下划线组成, 不能出现中文、 空格以及特殊字符等。 工程打开后如图 47.5.1所示:
图 47.5.1 OV5640以太网视频传输工程
然后将OV5640摄像头插入开发板上的摄像头扩展接口(注意摄像头镜头朝外) , 然后将网线一端连接电脑网口, 另一端与开发板上的网口连接。 再将下载器一端连电脑, 另一端与开发
板上对应端口连接, 最后连接电源线并打开电源开关。开发板连接实物图如下图所示:
接下来我们下载程序, 验证OV5640以太网视频传输上位机显示功能。 工程打开后通过点击工 具 栏 中 的 “Programmer” 图 标 打 开 下 载 界 面 , 通 过 “Add File” 按 钮 选 择ov5640_rgb565_640x480_udp_pc/par/output_files 目 录 下 的“ov5640_rgb565_640x480_udp_pc.sof” 文件。 开发板电源打开后, 在程序下载界面点击“Hardware Setup” , 在弹出的对话框中选择当前的硬件连接为“USB-Blaster[USB-0]” 。 然后点击“Start” 将工程编译完成后得到的sof文件下载到开发板中, 如图 47.5.3所示:
图 47.5.3 程序下载完成界面
程序下载完成后并且硬件连接无误的话, 我们可以看到开发板上的以太网接口上的灯会不停的闪烁, 说明此时开发板正在向PC传输图像。 电脑需要绑定开发板的MAC地址和IP地址才能和开发板进行通信, 有关MAC地址和IP地址的绑定方法请大家参考“以太网通信实验” 的下载
验证部分。开发板的MAC地址和IP地址绑定成功后, 打开附赠资料提供的以太网视频上位机显示软件,打开的界面如下:
图 47.5.4 视频传输上位机显示软件打开界面
在这里端口号设置为1234, 见ip_send模块代码如下所示:
252 //16位源端口号: 1234 16位目的端口号: 1234
253 ip_head[5] <= {16’ d1234,16’ d1234};
端口号设置完成之后, 点击开始按钮, 此时可以看到上位机显示的图像画面, 视频实时显
示界面如下图所示:
图 47.5.5 视频显示实时画面
从上图可以看到, 上位机实时显示出了摄像头拍摄的画面, 说明以太网视频传输上位机显示实验验证成功。 需要注意的是, 我们为每幅图像中间增加了时间间隔(图像帧间隙) , 再加上传输图像所消耗的时间, 一秒钟传输9~10帧图像, 在拍摄运动的画面中可能会有点卡顿的现
象, 但整体看上去图像画面还是比较流畅的。我们现在打开wireshark, 界面如下图所示:
图 47.5.6 wireshark打开界面
双击上图所示的本地连接或者先选中本地连接, 再点击红框选中的蓝色按钮, 即可开始抓取本地连接的数据包, 抓取界面如下图所示:
图 47.5.7 wireshark本地连接打开界面
上图中抓取的数据包为开发板发送的图像数据, 单包发送一行数据为1280个字节, 第一行图像数据加帧头为1284个字节。 双击其中一包数据可以查看数据包的详细数据, 我们双击一个字节数为1284的数据包, 界面如下图所示:
图 47.5.8 wireshark抓取到的详细数据
从上图中可以看到, 图像帧头和我们程序中设置的值是一样的。 至此, 基于OV5640的以太网视频传输实验已经全部介绍完毕。