基于FPGA的OV5640上电时序的控制
OV5640上电时序图
在实际中我们要想OV5640实际工作起来,必须对OV5640进行上电时序控制,控制的时序如下:
我们主要控制的时间是t2、t3、t4,因为一般情况下上面的时序图我们只能使用FPGA控制PWDN、RESETB、XVCLK、SCCB,另外的两个信号是与硬件电路相连,无法直接控制。
上面时间具体的时间值如下:
OV5640上电代码
这里因为上面的时序图过于简单,我们直接给出代码,代码如下:
`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : nnzhang1996@foxmail.com
// Website :
// Module Name : ov5640_pwdn.v
// Create Time : 2020-02-09 10:56:00
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************
module ov5640_pwdn(
//System Interfaces
input sclk ,
input rst_n ,
//Ov5640 Interfaces
output reg ov5640_rst_n ,
output reg ov5640_pwdn ,
//Others
output reg pwdn_done
);
//========================================================================================\
//**************Define Parameter and Internal Signals**********************************
//========================================================================================/
localparam DELAY_6MS = 30_0000 ;
localparam DELAY_2MS = 10_0000 ;
localparam DELAY_21MS = 105_0000 ;
reg [18:0] cnt_6ms ;
reg [16:0] cnt_2ms ;
reg [20:0] cnt_30ms ;
//========================================================================================\
//************** Main Code **********************************
//========================================================================================/
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
cnt_6ms <= 19'd0;
else if(ov5640_pwdn == 1'b1)
cnt_6ms <= cnt_6ms + 1'b1;
else
cnt_6ms <= 19'd0;
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
ov5640_pwdn <= 1'b1;
else if(cnt_6ms >= DELAY_6MS)
ov5640_pwdn <= 1'b0;
else
ov5640_pwdn <= ov5640_pwdn;
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
cnt_2ms <= 17'd0;
else if(ov5640_pwdn == 1'b0)
cnt_2ms <= cnt_2ms + 1'b1;
else
cnt_2ms <= 17'd0;
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
ov5640_rst_n <= 1'b0;
else if(cnt_2ms >= DELAY_2MS)
ov5640_rst_n <= 1'b1;
else
ov5640_rst_n <= ov5640_rst_n;
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
cnt_30ms <= 21'd0;
else if(ov5640_rst_n == 1'b1)
cnt_30ms <= cnt_30ms + 1'b1;
else
cnt_30ms <= 21'd0;
always @(posedge sclk or negedge rst_n)
if(rst_n == 1'b0)
pwdn_done <= 1'b0;
else if(cnt_30ms >= DELAY_21MS)
pwdn_done <= 1'b1;
else
pwdn_done <= pwdn_done;
endmodule
OV5640上电代码的测试代码
为了方便学习上面的两个时序,我们这里给出测试代码:
`timescale 1ns / 1ps
`define CLOCK 20
// *********************************************************************************
// Project Name : OSXXXX
// Author : zhangningning
// Email : nnzhang1996@foxmail.com
// Website :
// Module Name : ov5640_pwdn_tb.v
// Create Time : 2020-02-09 11:19:45
// Editor : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// XXXX zhangningning 1.0 Original
//
// *********************************************************************************
module ov5640_pwdn_tb;
reg sclk ;
reg rst_n ;
wire ov5640_rst_n ;
wire ov5640_pwdn ;
initial begin
sclk = 1'b0;
rst_n <= 1'b0;
#(100*`CLOCK);
rst_n <= 1'b1;
end
always #(`CLOCK/2) sclk = ~sclk;
ov5640_pwdn ov5640_pwdn_inst(
//System Interfaces
.sclk (sclk ),
.rst_n (rst_n ),
//Ov5640 Interfaces
.ov5640_rst_n (ov5640_rst_n ),
.ov5640_pwdn (ov5640_pwdn ),
//Others
.pwdn_done (pwdn_done )
);
endmodule
整个OV5640的驱动代码到这里我们已经写完,代码包括SCCB协议配置摄像头、OV5640上电时序控制、DVP协议转换成数据流。而这些知识在我们前面的文章中已经写完,同学们可以查看之前的博客。
总结
创作不易,认为文章有帮助的同学们可以关注点赞支持。(工程也都在群中)对文章有什么看法或者需要更近一步交流的同学,可以加入下面的群: