基于FPGA实现OV5640摄像头的视频图像采集及VGA显示

        最近刚刚看完开源骚客的《揭秘摄像头视频采集系统》,里面留了个小bug,困扰了我很久,后面进过我认真的推算,发现是帧率计算错了,ov5640我配置的其实是30fps的,而vga配置了60fps了,由于他们的帧率不一致,导致了图像刷新会有断层现象。

           基于FPGA实现OV5640摄像头的视频图像采集及VGA显示_第1张图片

 

assign  cfg_array[266]  =       {8'h78, 16'h3808, 8'h04};       // DVPHO     (1024)
assign  cfg_array[267]  =       {8'h78, 16'h3809, 8'h00};       // DVPHO     (1024)
assign  cfg_array[268]  =       {8'h78, 16'h380a, 8'h02};       // DVPVO     (720)
assign  cfg_array[269]  =       {8'h78, 16'h380b, 8'hd0};       // DVPVO     (720)
                                            
assign  cfg_array[270]  =       {8'h78, 16'h380c, 8'h07};       // HTS       (1892)  
assign  cfg_array[271]  =       {8'h78, 16'h380d, 8'h64};       // HTS
assign  cfg_array[272]  =       {8'h78, 16'h380e, 8'h02};       // VTS       (740)
assign  cfg_array[273]  =       {8'h78, 16'h380f, 8'he4};       // VTS

有上面代码可以看出dvp输出大小是1892*740,有效数据是1024*720,而pclk=84Mhz,所以帧率=84Mhz/(1892*740*2)=29.998,

因为我们采用的是RGB565格式的,一个像素需要2个pclk,所以上面的算式里需要乘以2.所以帧率为30fps.这个地方一定要注意,不然后面就会出现图像断帧了。

基于FPGA实现OV5640摄像头的视频图像采集及VGA显示_第2张图片

所以最后ov5640的图像信息是:1024*720 30fps.然后经过查找vga标准

发现适合我们的,只有1024*768 60Hz这种适合,至于768比720大48,我们只需要把vga的上下各减去24即可。配置代码如下

// 1024 x 768 @ 60Hz 65.000MHz 
parameter   LinePeriod      =       1344                        ;
parameter   H_SyncPulse     =       136                         ;
parameter   H_BackPorch     =       160                         ;
parameter   H_ActivePix     =       1024                        ;
parameter   Hde_start       =       H_SyncPulse + H_BackPorch   ; 
parameter   Hde_end         =       Hde_start + H_ActivePix     ; 

parameter   FramePeriod     =       806                         ;
parameter   V_SyncPulse     =       6                           ;
parameter   V_BackPorch     =       29                          ;
parameter   V_ActivePix     =       768                         ;
parameter   Vde_start       =       V_SyncPulse + V_BackPorch   ; 
parameter   Vde_end         =       Vde_start + V_ActivePix     ; 

所以最终的结果是vga的帧率是ov5640的2倍,所以ov5640每输出一帧图像,vga要刷新2次才能除去段帧现象。具体体现在sdram_read的rd_bank上。一帧图像显示完后,不能马上就进行rd_bank翻转,要确保刷新完2次,才能去翻转,还有就是要和ov5640_vsync进行同步一下,具体代码如下:

//----------------------------------------------------------------------
//ov5640_vsync_r
always  @(posedge clk or negedge rst_n)begin
    if(rst_n == 1'b0)begin
        ov5640_vsync_r  <=  4'd0;
    end
    else begin
        ov5640_vsync_r  <=  {ov5640_vsync_r[2:0],ov5640_vsync};
    end
end

assign  ov5640_vsync_neg    =   ov5640_vsync_r[3] && (~ov5640_vsync_r[2]);

//state_bank_c
always@(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        state_bank_c <= IDLE;
    end
    else begin
        state_bank_c <= state_bank_n;
    end
end

//state_bank_n
always@(*)begin
    case(state_bank_c)
        IDLE:begin
            if(ov5640_vsync_neg)begin
                state_bank_n = S1;
            end
            else begin
                state_bank_n = state_bank_c;
            end
        end
        S1:begin
            if(end_row_cnt)begin
                state_bank_n = S2;
            end
            else begin
                state_bank_n = state_bank_c;
            end
        end
        S2:begin
            if(end_row_cnt)begin
                state_bank_n = IDLE;
            end
            else begin
                state_bank_n = state_bank_c;
            end
        end
        default:begin
            state_bank_n = IDLE;
        end
    endcase
end

//rd_bank
always  @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
        rd_bank <=  2'b11;
    end
    else if(state_bank_c == S2 && end_row_cnt)begin
        rd_bank <=  ~rd_bank;
    end
end
//----------------------------------------------------------------------

福利:

为了能及时回复大家,现在获取源码方式如下:
微信扫描下面的二维码关注【春哥笔记】公众号,回复“ov5640”即可Get源码的获取方式:

基于FPGA实现OV5640摄像头的视频图像采集及VGA显示_第3张图片

你可能感兴趣的:(FPGA,0v5640)