Menu Close

图像采集与传输系统(摄像头驱动)

在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模组连接框图:

%title插图%num

ov5640 上电和复位模块, 主要用于在初始化之前, 对ov5640 硬件进行上电和对ov5640 芯片复位。上电和复位逻辑遵循ov5640芯片手册:首先对芯片上电(PWDN),然后等待。

参考目录:图像采集与传输系统的设计

 

OV5640 上电时序图:

%title插图%num

t2 > 5ms; t3 > 1ms; t4 > 20ms

 

 

%title插图%num

摄像头初始化代码:

`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)提供操作允许信号。

Posted in FPGA, FPGA 教材教案, IC, Verilog, 教材与教案, 文章

发表回复

相关链接