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

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

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

  • sigtab抓取数据

OV7670读操作的更多相关文章

  1. NoSql数据库初探-mongoDB读操作

    MongoDB以文档的形式来存储数据,此结果类似于JSON键值对.文档类似于编程语言中将键和值关联起来的结构(比如:字典.Map.哈希表.关联数组).MongoDB文档是以BOSN文档的形式存在的.B ...

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

    本质:读操作,用mysql_num_rows函数,写操作用mysql_affected_rows函数 mysql_num_rows() 返回结果集中行的数目.此命令仅对 SELECT 语句有效.要取得 ...

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

    http://www.osyunwei.com/archives/7464.html (学习运维知识好站) 说明: 操作系统:CentOS 5.X 64位 MySQL主服务器:192.168.21.1 ...

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

    出处:http://blog.chinaunix.net/uid-28852942-id-3992727.html这篇文章不是介绍 nand flash的物理结构和关于nand flash的一些基本知 ...

  5. LVS+Keepalived实现MySQL从库读操作负载均衡配置

    转载于osyunwei 说明: 操作系统:CentOS 5.X 64位 MySQL主服务器:192.168.21.126 MySQL从服务器:192.168.21.127,192.168.21.128 ...

  6. 为什么ConcurrentHashMap的读操作不需要加锁?

    我们知道,ConcurrentHashmap(1.8)这个并发集合框架是线程安全的,当你看到源码的get操作时,会发现get操作全程是没有加任何锁的,这也是这篇博文讨论的问题--为什么它不需要加锁呢? ...

  7. python的读写和写读操作

    # 读写操作 (读写操作是正常的)f = open('log',mode='r+',encoding='utf-8') # log是文件名 print(f.read()) f.write(" ...

  8. operator[],识别读操作和写操作

    body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...

  9. 通过vb.net 和NPOI实现对excel的读操作

    通过vb.net 和NPOI实现对excel的读操作,很久很久前用过vb,这次朋友的代码是vb.net写的需要一个excel的操作, 就顾着着实现功能了,大家凑合着看吧 Option Explicit ...

随机推荐

  1. python 文件打开小知识

    一个文件被打开后,你有一个file对象,你可以得到有关该文件的各种信息. file.name : 返回文件的名称 file.closed: 文件关闭返回值为True,否则为False file.mod ...

  2. python3.6成功安装scrapy

    本文基于环境:win10(64)+python3.6(64) 第一次直接pip install scrapy,安装出错,错误提示 error: Microsoft Visual C++ 14.0 is ...

  3. JDBC连接数据库的基本步骤

    第一步:注册驱动==>:Class.forName("数据库驱动的完整名称(mysql的数据库驱动名称:com.mysql.jbdc.Driver)"); 第二步:创建一个数 ...

  4. [入门向选讲] 插头DP:从零概念到入门 (例题:HDU1693 COGS1283 BZOJ2310 BZOJ2331)

    转载请注明原文地址:http://www.cnblogs.com/LadyLex/p/7326874.html 最近搞了一下插头DP的基础知识……这真的是一种很锻炼人的题型…… 每一道题的状态都不一样 ...

  5. Learn c language the one day

    第一个c程序 #include<stdio.h> int main() { ; ; printf_s("请输入两个数字:"); scanf_s("%d,%d& ...

  6. [ZYNQ-7]PS处理PL外部中断的简单实例的剖析 (参考米联miz702n)

    Zynq的ARM通过GIC中断控制器来接收核仲裁所有的中断.由于中断向量表只有4Bytes大小,仅仅正好存放一条跳转语句,因此当产生一个外部中断时,中断处理的大致过程:PC内容保存到LR_IRQ用于中 ...

  7. JavaScript基础知识(一)

    一.JavaScript基础 1.JavaScript用法: HTML 中的脚本必须位于 <script> 与 </script> 标签之间. 脚本可被放置在 HTML 页面的 ...

  8. 使用jdbc调用存储,函数

    public class JdbcTest {        private Connection conn = null;    private PreparedStatement pst = nu ...

  9. Linux 磁盘分区修改与管理

    --Linux 磁盘分区修改与管理 -----------------------------2014/03/05 1. 目的,将磁盘卷/dev/cciss/c0d0p8修改成新的用途. 原: /de ...

  10. U3D操作游戏对象

    游戏对象:所有出现在场景中的实体都是游戏对象. 一.创建游戏对象 创建游戏对象有两种方式:一是通过在unity中创建模型,而是通过脚本动态创建游戏对象.通过脚本动态创建的灵活性较高,重点也在于通过脚本 ...