集成电路技术分享

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
查看: 1408|回复: 3

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

[复制链接]
zxopenluyutong 发表于 2021-4-16 19:12:52 | 显示全部楼层 |阅读模式
本设计用到的FPGA开发板是Digilent Nexys_Video 开发板,程序的基础是正点原子为其FPGA产品提供的驱动程序,由于板子硬件的不同,我做了一些改动,使之能在Nexys_Video上运行,正点原子程序在其官网可以下载。HDMI驱动用的是Digilent提供的IP核,在其官网可以下载。

vivado 版本 2018.1

摄像头用的是这个



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



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

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

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

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

根据协议对寄存器的配置,输出视频流大小为1024x768,每一个像素点是16位,所以,生成如下大小的双端口BRAM

注:实际开发板上也有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};
lihongkun16 发表于 2021-4-17 08:40:46 | 显示全部楼层
OV5640摄像头模块FPGA驱动及HDMI显示
zhangyukun 发表于 2021-4-17 11:35:25 | 显示全部楼层
OV5640摄像头模块FPGA驱动及HDMI显示
雷磊 发表于 2021-4-17 14:49:47 | 显示全部楼层
OV5640摄像头模块FPGA驱动及HDMI显示
您需要登录后才可以回帖 登录 | 我要注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

QQ|小黑屋|手机版|Archiver|集成电路技术分享 ( 京ICP备20003123号-1 )

GMT+8, 2024-4-20 09:08 , Processed in 0.067443 second(s), 19 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表