OV7670读操作

这篇文章主要介绍一下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 <= 1‘d1;
        sda_reg <= 1‘d1;
        riic_data <= 1‘d0;
    end
    else if(dir == 1‘b1)    //read
        case(time_cnt)
            //idle
            6‘d0 : begin
                        iic_clk1 <= 1‘d1;
                        sda_reg <= 1‘d1;
                   end
            //start
            6‘d1 :begin
                        iic_clk1 <= 1‘d1;
                        sda_reg <= 1‘d0;
                  end
            6‘d2 :begin
                        iic_clk1 <= 1‘d0;
                        sda_reg <= 1‘d0;
                  end

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

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

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

  • sigtab抓取数据

时间: 2024-10-12 10:37:57

OV7670读操作的相关文章

对于linux中读操作

关于文件的读写,实在是太过于复杂,细节太多,所以只能分析他的原理,细节牵涉太多. 本文介绍文件的读操作. 先说一下读操作的轮廓.这个读操作是从磁盘把数据读入到内核缓冲区,数据在内核缓冲区被组织成radix_tree形式,然后在把这个缓冲区的内容拷贝到用户缓冲区,用户就可以操作自己缓冲区内的数据了. 具体一点就是: 对于每一进程打开的文件,都拥有一个文件对象描述符,从文件对象描述符中可以寻找到索引节点,从索引节点又可以找到adress_space,这个对象就是文件在内存中的缓存.因此,每一个打开此

怎么看时序图--nand flash的读操作详解(转载)

出处:http://blog.chinaunix.net/uid-28852942-id-3992727.html这篇文章不是介绍 nand flash的物理结构和关于nand flash的一些基本知识的.你需要至少了解 你手上的 nand flash的物理结构和一些诸如读写命令 操作的大概印象,你至少也需要看过 s3c2440中关于nand flash控制寄存器的说明. 由于本人也没有专门学过这方面的知识,下面的介绍也是经验之谈. 这里 我用的 K9F2G08-SCB0 这款nand flas

c#文件之读操作摸索学习

主要知识点: 一. FileStream file_read = new FileStream("1.txt", FileMode.Open, FileAccess.Read);//只读权限打开1.txt文件 参数1: "1.txt":文件路径,通常用字符串变量或者字符串常量表示,如:"d:\\1.txt"; 参数2: FileMode.Open:打开模式,此种方式如果存在则打开,否则抛出异常. FileMode.Append:追加模式,打开文件

FileInputStream 原理总结 把文件作为字节流进行读操作

package io; import java.io.FileInputStream; import java.io.IOException; public class IOUtil { /** * 读取指定文件内容,按照16进制输出到控制台,为什么要按十六进制? * 并且每输出10个byte换行 * @throws IOException */ public static void printHex(String filename) throws IOException{ //把文件作为字节流

9.NandFlash的驱动_读操作2440

9.NandFlash的驱动_读操作 在Makefile里添加nand.o,然后新建一个nand.c来实现NandFlash的读操作. 对NandFlash的读方式有两种: 按页读(需要提供页地址,也就是行地址). 随机读(就是读取页里的某一列,需要提供页地址,也就是行地址和列地址). 实现页读需要两个操作,一个是页地址,另一个是存放读出的数据的变量.所以定义的函数的原型: void NF_PageRead(unsigned long addr,unsigned char* buff) 该函数根

NoSql数据库初探-mongoDB读操作

MongoDB以文档的形式来存储数据,此结果类似于JSON键值对.文档类似于编程语言中将键和值关联起来的结构(比如:字典.Map.哈希表.关联数组).MongoDB文档是以BOSN文档的形式存在的.BSON是JSON附加了类型信息的一种二进制的表现形式. 文档中的字段可以是任何BSON类型,比如(文档类型.数组.文档数组) MongoDB将所有文档存储在collection中,collection是一组相关的文档集合,这一组文档集合拥有共同的索引,collection类似于关系型数据库中的表.

怎么看时序图--nand flash的读操作详解 (转)

这篇文章不是介绍 nand flash的物理结构和关于nand flash的一些基本知识的.你需要至少了解 你手上的 nand flash的物理结构和一些诸如读写命令 操作的大概印象,你至少也需要看过 s3c2440中关于nand flash控制寄存器的说明. 由于本人也没有专门学过这方面的知识,下面的介绍也是经验之谈. 这里 我用的 K9F2G08-SCB0 这款nand flash 来介绍时序图的阅读.不同的芯片操作时序可能不同,读的命令也会有一些差别. 当然其实有时候像nand flash

CI中获取读操作的结果集行数+获取写操作的影响行数

本质:读操作,用mysql_num_rows函数,写操作用mysql_affected_rows函数 mysql_num_rows() 返回结果集中行的数目.此命令仅对 SELECT 语句有效.要取得被 INSERT,UPDATE 或者 DELETE 查询所影响到的行的数目,用 mysql_affected_rows(). CI中的方法: 读操作,获取行数: $query->num_rows() 该函数将会返回当前请求的行数.在本例子中, $query 表示当前 SQL 所产生的请求结果对象:

LVS+Keepalived实现MySQL从库读操作负载均衡

http://www.osyunwei.com/archives/7464.html (学习运维知识好站) 说明: 操作系统:CentOS 5.X 64位 MySQL主服务器:192.168.21.126 MySQL从服务器:192.168.21.127,192.168.21.128 MySQL主从同步的数据库为:osyunweidb 实现目的: 增加两台服务器(主备),通过LVS+Keepalived实现MySQL从库读操作负载均衡 架构规划: 操作系统:CentOS 5.X 64位 LVS主