FPGA读取ov5642摄像头

豪威的ov系列的摄像头可谓在FPGA图像处理中应用广泛,虽然博主利用黑金给的教材直接跑程序就可以得到摄像头的实时显示,但是无奈黑金给的代码太多,太繁琐。看了半天勉强看懂每个文件的大体意思,知道了之间的关系,会改改基本参数,仅此而已。那还毕业毛业啊这样。。。所以博主打算自己编写一套完整的系统来实现读取摄像头并且进行图像处理,然后实时显示的系统。虽然说万事开头难,但是怎么说呢,不积跬步,无以至千里。所以博主打算先成功读取豪威的摄像头啊。

首先豪威ov5642的摄像头和5640很相似,都是用iic进行通信的,虽然豪威官方的通信方式是SCCB,但是不同之处只是在读数据时候时序有些不同,由于我们是配置寄存器,往里面写数据的,所以时序一模一样的。关于iic的通信这里就不多介绍了,博主有相关的博客可以参考,只是补充一点,这里设备的地址不再是8位而是16位了,所以应答需要两次。由于黑金给的板子比较良心,不需要上电启动,直接配置寄存器即可,所以没有一点难度。建议先做下仿真看看时序有没有问题。。。

好了,寄存器配置完后,我们自己设置一个done信号来提示寄存器已经配置完毕,像素数据要输出了。其实我发现done信号可有可无,因为相机自己会有一个像素有效信号href,这个信号有效,就可以读数据。这样就可以抓数据啦怎么抓呢,就是通过ila将data信号获取,然后看一行data数据的个数来判断是否读对了。来看结果

看,这里显示href有效的一个周期内总共有1280个数据,由于我们设置的分辨率是640的,正好是一半,所以说明我们的代码没有问题。代码很简单,就是iic的代码,配置完直接读取数据就行。。

    
    START: begin
        if(count>=16'd0&&count<=16'd299)
            slk<=1'b1;
        else
            slk<=1'b0;
        
        if(count>=16'd0&&count<=16'd200)
            sda<=1'b1;
        else
            sda<=1'b0;
        
        if(count==16'd499&&writecount==6'd0)
            STATE<=WRITE_DEVICE;
    end
    WRITE_DEVICE: begin
        if(count>=16'd0&&count<=16'd124)
            slk<=1'b0;
        else if(count>=16'd125&&count<=16'd374)
            slk<=1'b1;
        else if(count>=16'd375&&count<=16'd499)
            slk<=1'b0;
        
        if(writecount==6'd7&&count==16'd499)
        begin
            STATE<=ASK;
            writecount<=writecount+1'b1;
            //ask sda 1'bz
            //sda<=1'bz;
        end
        else if(count==16'd499)
            writecount<=writecount+1'b1;
        else
            writecount<=writecount;    
        //写设备地址
        sda<=writedata[6'd31-writecount];
    end
    WRITE_HIGHADD: begin
        if(count>=16'd0&&count<=16'd124)
            slk<=1'b0;
        else if(count>=16'd125&&count<=16'd374)
            slk<=1'b1;
        else if(count>=16'd375&&count<=16'd499)
            slk<=1'b0;
        
        if(writecount==6'd15&&count==16'd499)
        begin
            STATE<=ASK;
            writecount<=writecount+1'b1;
            //ask sda 1'bz
            //sda<=1'bz;
        end
        else if(count==16'd499)
            writecount<=writecount+1'b1;
        else
            writecount<=writecount;    
        //写设备地址
        sda<=writedata[6'd31-writecount];
    end 
    WRITE_LOWADD: begin
        if(count>=16'd0&&count<=16'd124)
            slk<=1'b0;
        else if(count>=16'd125&&count<=16'd374)
            slk<=1'b1;
        else if(count>=16'd375&&count<=16'd499)
            slk<=1'b0;
        
        if(writecount==6'd23&&count==16'd499)
        begin
            STATE<=ASK;
            writecount<=writecount+1'b1;
            //ask sda 1'bz
            //sda<=1'bz;
        end
        else if(count==16'd499)
            writecount<=writecount+1'b1;
        else
            writecount<=writecount;    
        //写设备地址
        sda<=writedata[6'd31-writecount];
    end 
    WRITE_DATA: begin
        if(count>=16'd0&&count<=16'd124)
            slk<=1'b0;
        else if(count>=16'd125&&count<=16'd374)
            slk<=1'b1;
        else if(count>=16'd375&&count<=16'd499)
            slk<=1'b0;
        
        if(writecount==6'd31&&count==16'd499)
        begin
            STATE<=ASK;
           // writecount<=writecount+1'b1;
            //ask sda 1'bz
            //sda<=1'bz;
        end
        else if(count==16'd499)
            writecount<=writecount+1'b1;
        else
            writecount<=writecount;    
        //写设备地址
        sda<=writedata[6'd31-writecount];
    end 
    STATE_END: begin
    if(count>=16'd0&&count<=16'd200)
        slk<=1'b0;
    else
        slk<=1'b1;
    
    if(count>=16'd0&&count<=16'd300)
        sda<=1'b0;
    else
        sda<=1'b1;
    
    if(count==16'd499)
        STATE<=DONE;
end 
    ASK: begin
        if(count>=16'd0&&count<=16'd124)
            slk<=1'b0;
        else if(count>=16'd125&&count<=16'd374)
            slk<=1'b1;
        else if(count>=16'd375&&count<=16'd499)
            slk<=1'b0;
        
        if(count==16'd249)
            isask<=sda;
        
        if(count==16'd499)
        begin
            sda<=1'b0;
            STATE<=IS_ASK;
        end
        else
            sda<=1'bz;
    end
    IS_ASK : begin
        //if(isask!=0&&writecount==6'd7)
        //begin
           //STATE<=WRITE_DEVICE;
            //writecount<=6'd0;
        //end
        if(writecount==6'd8)
            STATE<=WRITE_HIGHADD;
        /*else if(isask==!0&&writecount==6'd15)
        begin
            STATE<=WRITE_HIGHADD;
            writecount<=6'd7;
        end*/
        else if(writecount==6'd16)
            STATE<=WRITE_LOWADD;
        /*else if(isask==!0&&writecount==6'd23)
        begin
            STATE<=WRITE_LOWADD;
            writecount<=6'd15;
        end*/
        else if(writecount==6'd24)
            STATE<=WRITE_DATA;
        /*else if(isask==!0&&writecount==6'd31)
        begin
            STATE<=WRITE_DATA;
            writecount<=6'd23;
        end*/
        else if(writecount==6'd31)
            STATE<=STATE_END;
    end
   DONE: begin
        writecount<=6'd0;
        isdone<=1'b1;
        STATE<=FINAL;
   end 
   FINAL:begin
        STATE<=START;
        isdone<=1'b0;
   end
   

 

FPGA读写OV5640摄像头显示例程 Verilog逻辑源码Quartus工程文件+文档说明,FPGA型号Cyclone4E系列中的EP4CE6F17C8,Quartus版本17.1。 本实验将采用 500 万像素的 OV5640 摄像头模组(模块型号:AN5640)为大家显示更高分辨率 的视频画面。OV5640 摄像头模组最大支持 QSXGA (2592x1944)的拍照功能,支持 1080P、720P、 VGA、QVGA 视频图像输出。本实验将 OV5640 配置为 RGB565 输出,先将视频数据写入外部存储 器,再从外部存储器读取送到 VGA、LCD 等显示模块。 module top( input clk, input rst_n, output cmos_scl, //cmos i2c clock inout cmos_sda, //cmos i2c data input cmos_vsync, //cmos vsync input cmos_href, //cmos hsync refrence,data valid input cmos_pclk, //cmos pxiel clock output cmos_xclk, //cmos externl clock input [7:0] cmos_db, //cmos data output cmos_rst_n, //cmos reset output cmos_pwdn, //cmos power down output vga_out_hs, //vga horizontal synchronization output vga_out_vs, //vga vertical synchronization output[4:0] vga_out_r, //vga red output[5:0] vga_out_g, //vga green output[4:0] vga_out_b, //vga blue output sdram_clk, //sdram clock output sdram_cke, //sdram clock enable output sdram_cs_n, //sdram chip select output sdram_we_n, //sdram write enable output sdram_cas_n, //sdram column address strobe output sdram_ras_n, //sdram row address strobe output[1:0] sdram_dqm, //sdram data enable output[1:0] sdram_ba, //sdram bank address output[12:0] sdram_addr, //sdram address inout[15:0] sdram_dq //sdram data ); parameter
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值