基于FPGA的DVP协议实现
DVP协议的介绍
DVP协议是摄像头中最常用到的协议,除了DVP协议摄像头中还有娶她常用的协议如:MIPI、LVDS等协议。这里给出DVP协议的时序图:
上面的HREF是行同步信号,还有VSYNC是场同步信号,从上面可以看出该时序与VGA时序相似性很高,只有HREF高低电平相反了。
DVP协议代码
从上面的时序图中我们可以将DVP协议转换成标准的数据流,代码如下:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : [email protected]
// Website :
// Module Name : dvp2data.v
// Create Time : 2020-02-08 23:30:48
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************
module dvp2data(
//System Interfaces
input rst_n ,
//OV5640 Interfaces
input ov5640_pclk ,
input ov5640_href ,
input ov5640_vsync ,
input [ 7:0] ov5640_data ,
//User Interfaces
output reg [15:0] data ,
output reg data_en
);
//========================================================================================\
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
reg flag_byte ;
wire ov5640_vsync_pos;
reg ov5640_vsync_r1 ;
reg [ 3:0] frame_cnt ;
reg frame_vaild ;
//========================================================================================\
//************** Main Code **********************************
//========================================================================================/
assign ov5640_vsync_pos = ov5640_vsync && ~ov5640_vsync_r1;
always @(posedge ov5640_pclk)
ov5640_vsync_r1 <= ov5640_vsync;
always @(posedge ov5640_pclk or negedge rst_n)
if(rst_n == 1'b0)
flag_byte <= 1'b0;
else if(ov5640_href == 1'b1)
flag_byte <= ~flag_byte;
else
flag_byte <= 1'b0;
always @(posedge ov5640_pclk or negedge rst_n)
if(rst_n == 1'b0)
data <= 8'd0;
else if(flag_byte == 1'b1)
data <= {data[15:8],ov5640_data};
else
data <= {ov5640_data,data[7:0]};
always @(posedge ov5640_pclk or negedge rst_n)
if(rst_n == 1'b0)
data_en <= 1'b0;
else if(flag_byte == 1'b1 && frame_vaild == 1'b1)
data_en <= 1'b1;
else
data_en <= 1'b0;
always @(posedge ov5640_pclk or negedge rst_n)
if(rst_n == 1'b0)
frame_cnt <= 4'd0;
else if(ov5640_vsync_pos == 1'b1 && frame_vaild == 1'b0)
frame_cnt <= frame_cnt + 1'b1;
else
frame_cnt <= frame_cnt;
always @(posedge ov5640_pclk or negedge rst_n)
if(rst_n == 1'b0)
frame_vaild <= 1'b0;
else if(frame_cnt >= 'd10)
frame_vaild <= 1'b1;
else
frame_vaild <= frame_vaild;
endmodule
rst_n :模块复位信号
ov5640_pclk :模块的时钟信号,对于OV5640摄像头是24MHz
ov5640_href :OV5640摄像头中DVP的行同步信号
ov5640_vsync :OV5640摄像头中DVP的场同步信号
ov5640_data :OV5640摄像头中DVP的数据信号
data :模块的输出数据信号
data_en :模块输出数据信号的使能信号
DVP协议的测试代码
与我们之前的代码相同,这里给出测试代码,如下:
`timescale 1ns / 1ps
`define CLOCK 20
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : [email protected]
// Website :
// Module Name : dvp2data_tb.v
// Create Time : 2020-02-08 22:01:07
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************
module dvp2data_tb;
reg rst_n ;
reg ov5640_pclk ;
reg ov5640_href ;
reg ov5640_vsync ;
reg [ 7:0] ov5640_data ;
wire [15:0] data ;
wire data_en ;
initial begin
ov5640_pclk = 1'b0;
rst_n <= 1'b0;
ov5640_href <= 1'b0;
ov5640_vsync <= 1'b0;
ov5640_data <= 8'd0;
#(100*`CLOCK);
rst_n <= 1'b1;
repeat(12)begin
#(500*`CLOCK)
dvp_data();
end
end
always #(`CLOCK/2) ov5640_pclk = ~ov5640_pclk;
task dvp_data;
integer i,j ;
begin
ov5640_vsync <= 1'b0;
#(10*`CLOCK);
ov5640_vsync <= 1'b1;
#(10*`CLOCK);
ov5640_vsync <= 1'b0;
#(100*`CLOCK);
for(i=0;i<720;i=i+1)begin
for(j=0;j<1080*2;j=j+1)begin
ov5640_href <= 1'b1;
#(`CLOCK);
ov5640_data <= ov5640_data + 1'b1;
end
ov5640_href <= 1'b0;
#(`CLOCK*100);
end
ov5640_data <= 8'd0;
end
endtask
dvp2data dvp2data_inst(
//System Interfaces
.rst_n (rst_n ),
//OV5640 Interfaces
.ov5640_pclk (ov5640_pclk ),
.ov5640_href (ov5640_href ),
.ov5640_vsync (ov5640_vsync ),
.ov5640_data (ov5640_data ),
//User Interfaces
.data (data ),
.data_en (data_en )
);
endmodule
总结
创作不易,认为文章有帮助的同学们可以关注点赞支持。(工程也都在群中)对文章有什么看法或者需要更近一步交流的同学,可以加入下面的群: