OV5640摄像头模块FPGA驱动及HDMI显示

本设计用到的FPGA开发板是Digilent Nexys_Video 开发板,程序的基础是正点原子为其FPGA产品提供的驱动程序,由于板子硬件的不同,我做了一些改动,使之能在Nexys_Video上运行,正点原子程序在其官网可以下载。HDMI驱动用的是Digilent提供的IP核,在其官网可以下载。

vivado 版本 2018.1

摄像头用的是这个

OV5640摄像头模块FPGA驱动及HDMI显示_第1张图片

首先用Clocking Wizard生成摄像头核HDMI IP核需要的65M时钟。

OV5640摄像头模块FPGA驱动及HDMI显示_第2张图片

摄像头的驱动是用SCCB协议配置寄存器,正点原子给提供了,直接用就好了。

在其驱动最后的输出模块中,输出了两个信号:分别是cmos_frame_valid,cmos_frame_data。一个是有效信号,一个是数据。我们就用这两个信号就可以了。

获得的数据是不能直接传送到HDMI去显示的,因为OV5640模块产生的行信号很不好,并且有效信号并不是连续的(OV5640每次传送8bit的数据,而RGB565格式下,一个像素需要两次传输才能获得,所以有效信号是隔一个时钟周期才有效一次),并且,对OV5640的不同配置可能导致模块的PCLK不同,所以这里需要通过一些媒介对数据进行缓存。

在正点原子原程序中,视频流会被存储在SDRAM中,这里由于我的开发板资源很大,用BRAM就装下了。

根据协议对寄存器的配置,输出视频流大小为1024x768,每一个像素点是16位,所以,生成如下大小的双端口BRAMOV5640摄像头模块FPGA驱动及HDMI显示_第3张图片

注:实际开发板上也有DDR3存储器,但是其需要用MIG IP核驱动,相对麻烦,在有处理器的SOC中可以用MIG内核,我也已经实现过,如果有空我就再写出来。

根据写有效信号驱动写地址变化

always @(posedge cam_pclk,negedge rst_n) begin
    if(~rst_n) begin
        addra<=0;
    end else begin
        if(wr_en) begin
            addra<=addra+1;
            if(addra==20'hc0000-1) addra<=0;
        end
    end
end

读地址同理实现

always @(posedge clk_65m,negedge rst_n) begin
    if(~rst_n) begin
        addrb<=0;
    end else begin
        if(rd_en) begin
            addrb<=addrb+1;
            if(addrb==20'hc0000-1) addrb<=0;
        end
    end
end

最后连上HDMI IP核即可。由于该IP核是24位,并且绿蓝像素位置貌似反了,所以要对数据进行处理。

 vid_pData<={rd_data[15:11],3'b0,rd_data[4:0],3'b0,rd_data[10:5],2'b0};

工程下载地址:

https://download.csdn.net/download/dongze2/11224991

你可能感兴趣的:(Nexys_Video)