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
   

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值