在PRX100T-D 开发板中, ov5640模组使用dvp(digital video port) 和 FPGA 相连,其中:
- CAM_SCL,CAM_SDA 为FPGA 配置ov5640通道,用于配置ov5640相关的寄存器;
- 同时FPGA 开发板提供24M 的标准时钟给ov5640,
- FPGA提供CAM_PWUP信号用于给ov5640上电,
- ov5640模组周边硬件会根据CAM_PWUP信号,产生CAM_RESETB,用于ov5640芯片的复位。
PRX100T-D 开发板和ov5640模组连接框图:
ov5640 上电和复位模块, 主要用于在初始化之前, 对ov5640 硬件进行上电和对ov5640 芯片复位。上电和复位逻辑遵循ov5640芯片手册:首先对芯片上电(PWDN),然后等待。
参考目录:图像采集与传输系统的设计
OV5640 上电时序图:
t2 > 5ms; t3 > 1ms; t4 > 20ms
摄像头初始化代码:
`timescale 1ns / 1ps
// OV5640模块正确上电的模块。摄像头模块的上电是需要遵循一定的上电时序的,
// 具体的上电顺序可以参考PPT中相关内容或者OV5640的PDF文档,此处不再赘述。
module power_on_delay_ov5640_phy(
input clk_50m, // 50M 时钟,摄像头的配置在
input rst_n, // 同步于50M时钟的复位信号。
// The camera is powered on
output reg initial_en = 0, // 5640摄像头正常供电的驱动信号
output reg camera_pwup = 0, // 5640摄像头正常供电的驱动信号
output reg cam_resetb = 0 // 5640摄像头正常供电的驱动信号
);
// 定义一个多位计数器,通过计数器的自加1,建立一个时间轴,
// 在此时间轴上不同时间点,给出5640正确上电的驱动信号即可。
reg [31:0] cam_pwr_cnt = 0 ;
always @ ( posedge clk_50m )
if( rst_n == 1'b0 )
cam_pwr_cnt <= 0;
else
begin
if (cam_pwr_cnt < 200_000_000)
cam_pwr_cnt <= cam_pwr_cnt + 1 ;
else
cam_pwr_cnt <= cam_pwr_cnt ;
end
// camera_pwup signal generate
always @ ( posedge clk_50m )
if(rst_n == 1'b0)
camera_pwup <= 0;
else
begin
if (cam_pwr_cnt == 20_000_000)
camera_pwup <= 1;
else
camera_pwup <= camera_pwup ;
end
// cam_resetb signal generate
always @ ( posedge clk_50m )
if(rst_n == 1'b0)
cam_resetb <= 0;
else
begin
if (cam_pwr_cnt == 40_000_000)
cam_resetb <= 1;
else
cam_resetb <= cam_resetb ;
end
// initial_en signal generate
always @ ( posedge clk_50m )
if(rst_n == 1'b0)
initial_en <= 0;
else
begin
if (cam_pwr_cnt == 180_000_000)
initial_en <= 1;
else
initial_en <= initial_en;
end
endmodule
代码分析:
reg [31:0] cam_pwr_cnt = 0 ;
always @ ( posedge clk_50m )
if( rst_n == 1'b0 )
cam_pwr_cnt <= 0;
else
begin
if (cam_pwr_cnt < 200_000_000)
cam_pwr_cnt <= cam_pwr_cnt + 1 ;
else
cam_pwr_cnt <= cam_pwr_cnt ;
end
提供一个绝对时间的标尺, 在上电后cam_pwr_cnt 清零,之后每个时钟下都在计数, 知道计数器 等于 200_000_000时,停止计数。
// camera_pwup signal generate
always @ ( posedge clk_50m )
if(rst_n == 1'b0)
camera_pwup <= 0;
else
begin
if (cam_pwr_cnt == 20_000_000)
camera_pwup <= 1;
else
camera_pwup <= camera_pwup ;
end
在标尺计数器 = 20_000_000 时,将camera_pwup 信号置一, 在这之前, camera_pwup 信号一直为零。
cam_resetb 信号在工程顶层文件中没有连接(这个信号没有被使用)。
// initial_en signal generate
always @ ( posedge clk_50m )
if(rst_n == 1'b0)
initial_en <= 0;
else
begin
if (cam_pwr_cnt == 180_000_000)
initial_en <= 1;
else
initial_en <= initial_en;
end
在标尺计数器为 180_000_000时, 将初始化有效信号(initial_en)置一, 在这之前 initial_en 信号一直为零。当initial_en 信号有效时, 配置模块就可以对ov5641的寄存器做读写操作了。
这个模块主要是为了提供ov5640上电,reset 操作, 同时输出initail_en 信号为其他模块(配置ov5640)提供操作允许信号。


