码迷,mamicode.com
首页 > 其他好文 > 详细

OV7670读操作

时间:2017-09-15 20:10:38      阅读:190      评论:0      收藏:0      [点我收藏+]

标签:.com   地址   default   stop   模式   always   logs   部分   star   

这篇文章主要介绍一下verilog读ov7670的出厂序列号

技术分享

技术分享

读时序共分为五个部分

  • 首先发送start,然后发送OV7670的器件地址,ov6070的ID是0x42,0x42+一位响应位
  • 发送ov7670的寄存器地址,这里可以读取它的厂商识别号 ,比如1c  发送八位寄存器+接受一位响应位
  • ov7670的SCCB时序不同与iic时序,在发送完第一个部分需要比iic时序多发送一个stop,那就是stop+start
  • 再次发送ov7670的器件地址,这次需要指定读写,第八位是读写控制位,0是写,1是读,即0x43+响应位
  • 最后就是接受数据,需要注意的是最后不是响应位,而是NA,发送高电平即可,最后跟一个结束stop

ov7670管脚

  • pwdn是睡眠模式,0工作,1睡眠
  • rst_n  复位   低电平复位 高电平工作
  • XCLK系统时钟输入 官方手册推荐使用24M
  • SCl IIC时钟引脚  我用的是100K
  • SDA IIC数据输入   

简单的列一下程序

  • 100K时钟产生

技术分享

IIC时钟对时钟要求不严格,所以采用进位的方法进行分频,所产生的时钟频率略小于100K,

div_en是使能信号,如果采用使能时钟可能会出现问题。

  • 时序采用状态机的方法一步步执行,相对比较直观

技术分享

  • 响应标志位,因为数据位是双向口,需要在响应时间设置位输入

技术分享

  • 状态机
//--------------------------------
//Funtion : sda_reg

always @(posedge clk or negedge rst_n)
begin
    if(!rst_n)
    begin
        iic_clk1 <= 1d1;
        sda_reg <= 1d1;
        riic_data <= 1d0;
    end
    else if(dir == 1b1)    //read
        case(time_cnt)
            //idle
            6d0 : begin
                        iic_clk1 <= 1d1;
                        sda_reg <= 1d1;  
                   end
            //start
            6d1 :begin
                        iic_clk1 <= 1d1;
                        sda_reg <= 1d0;
                  end
            6d2 :begin
                        iic_clk1 <= 1d0;
                        sda_reg <= 1d0;
                  end
                        
            //ID_addr
            6d3 :        sda_reg <= wdata_reg[23];
            6d4 :        sda_reg <= wdata_reg[22];
            6d5 :        sda_reg <= wdata_reg[21];
            6d6 :        sda_reg <= wdata_reg[20];
            6d7 :        sda_reg <= wdata_reg[19];
            6d8 :        sda_reg <= wdata_reg[18];
            6d9 :        sda_reg <= wdata_reg[17];
            6d10:        sda_reg <= wdata_reg[16];                
            //ack
            6d11:        iic_clk1<= 1d0;
            6d12:                       ;
            6d13:        iic_clk1<= 1d0;
            //sub_addr
            6d14:        sda_reg <= wdata_reg[15];
            6d15:        sda_reg <= wdata_reg[14];
            6d16:        sda_reg <= wdata_reg[13];
            6d17:        sda_reg <= wdata_reg[12];
            6d18:        sda_reg <= wdata_reg[11];
            6d19:        sda_reg <= wdata_reg[10];
            6d20:        sda_reg <= wdata_reg[9];
            6d21:        sda_reg <= wdata_reg[8];    
            //ack
            6d22:        iic_clk1<= 1d0;
            6d23:                       ;
            6d24:        iic_clk1<= 1d0;
            //stop
            6d25:begin
                        iic_clk1 <= 1d1;
                        sda_reg  <= 1d0;
                  end
            6d26:begin
                        iic_clk1 <= 1d1;
                        sda_reg  <= 1d1;
                  end
            //start
            6d27:begin
                        iic_clk1 <= 1d1;
                        sda_reg  <= 1d1;
                  end
            6d28:begin
                        iic_clk1 <= 1d1;
                        sda_reg  <= 1d0;
                  end
            //ID_addr
            6d29:        sda_reg <= wdata_reg[7];
            6d30:        sda_reg <= wdata_reg[6];
            6d31:        sda_reg <= wdata_reg[5];
            6d32:        sda_reg <= wdata_reg[4];
            6d33:        sda_reg <= wdata_reg[3];
            6d34:        sda_reg <= wdata_reg[2];
            6d35:        sda_reg <= wdata_reg[1];
            6d36:        sda_reg <= wdata_reg[0];    
            //ack
            6d37:        iic_clk1<= 1d0;
            6d38:                       ;
            6d39:        iic_clk1<= 1d0;
            //read_data
            6d40:        riic_data[7] <= iic_sda;
            6d41:        riic_data[6] <= iic_sda;
            6d42:        riic_data[5] <= iic_sda;
            6d43:        riic_data[4] <= iic_sda;
            6d44:        riic_data[3] <= iic_sda;
            6d45:        riic_data[2] <= iic_sda;
            6d46:        riic_data[1] <= iic_sda;
            6d47:        riic_data[0] <= iic_sda;
            //nack
            6d48:        sda_reg <= 1d1;
            //stop
            6d49:begin
                        iic_clk1 <= 1d1;
                        sda_reg  <= 1d0;
                  end
            6d50:begin
                        iic_clk1 <= 1d1;
                        sda_reg  <= 1d1;
                  end
            default :
                    begin
                        iic_clk1 <= 1d1;
                        sda_reg  <= 1d1;
                    end
        endcase     
end
  • iic_clk和iic_sda

技术分享  sda是双向端口,在输入的1时候设置为高阻态

 dir是读写方向控制段,这里只是读所以置一

  • sigtab抓取数据

技术分享

 技术分享

OV7670读操作

标签:.com   地址   default   stop   模式   always   logs   部分   star   

原文地址:http://www.cnblogs.com/bixiaopengblog/p/7527942.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!