加载中…
个人资料
明德扬FPGA技术连载平台
明德扬FPGA技术连
载平台
  • 博客等级:
  • 博客积分:0
  • 博客访问:5,149
  • 关注人气:17
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
相关博文
推荐博文
谁看过这篇博文
加载中…
正文 字体大小:

边缘检测项目:摄像头配置模块ov7670_config代码解析

(2019-12-31 14:55:06)
标签:

fpga

明德扬

至简设计法

分类: FPGA
作者:肖肖肖
本文为明德扬原创文章,转载请注明出处!

摄像头配置模块的功能:根据摄像头配置指令模块ov7670_para的操作,产生对应的写寄存器命令、读寄存器命令给下游模块。具体功能如下:

1. 根据ov7670_para的参数,逐个配置或者读取寄存器;
2. 所有寄存器操作完成后,产生完成指示信号。

通过代码:`include“ov7670_para.v”,可以把边缘检测摄像头配置指令模块ov7670_para包含进本模块。

一、设计架构

摄像头配置模块采用两个计数器的架构:计数器reg_cnt表示的是对要配置的164个寄存器进行计数,计数器rw_cnt表示判断写数据还是读数据的时序。例如,在写时序时,判断参数是否要写寄存器,如果要写寄存器,此时才产生写命令,如果参数是不要写寄存器,此时也不产生写命令。其结构图如下:
边缘检测项目:摄像头配置模块ov7670_config代码解析
计数器rw_cnt:寄存器读写时序计数器。用来区分“向寄存器写数据”还是“从寄存器读数据”这两个状态。当其为0时,表示判断是否写寄存器的时序,当其为1时,表示判断是否读寄存器的时序。不管读写属性参数是什么,每个寄存器都会占有这两个时序。
计数器reg_cnt:寄存器顺序计数器。对摄像头164个寄存器进行排序,按顺序配置各个寄存器。


二、信号意义

信号
类型
意义
clk
输入信号
时钟信号
rst_n
输入信号
复位信号,低电平有效。
config_en
输入信号
配置开始指示信号。
当接收到该信号为1时,就开始对寄存器进行配置。
rdy
输入信号
下游sccb模块准备好指示信号。
0:下游sccb模块正忙,不能向sccb发送配置指令;
1:下游sccb模块空闲,可以向sccb发送配置指令。
rdata
输入信号
从 SCCB模块返回的读寄存器数据。
此工程没有用到。
rdata_vld
输入信号
从SCCB模块返回的数据有效指示信号。
此工程没有用到。
wdata
输出信号
向下游SCCB模块配置寄存器的数据,当写寄存器命令有效时,此数据才有效。
设计逻辑:该数据取自摄像头配置指令的低8位,表示向需要配置的摄像头寄存器中写入的数据。
addr
输出信号
配置寄存器的读写地址,当写寄存器命令或者读寄存器命令有效时,此数据才有效。
设计逻辑:无论读还是写寄存器,其值均来自于摄像头配置指令的第9位到第16位,表示需要操作的摄像头寄存器的地址。
wr_en
输出信号
写寄存器命令。
设计逻辑:在“判断是否写时序”的时候,如果在配置指令中次高位为1,此时写寄存器命令有效,否则为0。
rd_en
输出信号
读寄存器命令。
设计逻辑:在“判断是否读时序”的时候,如果在配置指令中最高位为1,此时读寄存器命令有效,否则为0。
cmos_en
输出信号
下游摄像头图像采集cmos_capture模块使能信号。
复位后为0;
设计逻辑:当164个摄像头寄存器配置完成后为1,指示下游cmos_capture模块开始图像采集。
pwdn
输出信号
此工程没有用到。
reg_cnt
内部信号
寄存器顺序计数器。
表示配置164个寄存器的顺序。
add_reg_cnt
内部信号
寄存器顺序计数器加一条件。
每当判断完寄存器读写时序后,开始下一个寄存器的配置。
end_reg_cnt
内部信号
寄存器顺序计数器结束条件。
表示按顺序配置完164个寄存器。
flag_add
内部信号
摄像头寄存器配置状态指示信号。
0:非配置寄存器状态;
1:配置寄存器状态。
add_wdata
内部信号
摄像头寄存器配置指令。
具体参数见摄像头配置指令模块ov7670_para。
rw_cnt
内部信号
寄存器读写时序计数器。
用来区分“向寄存器写数据”还是“从寄存器读数据”这两个状态。
0:表示判断是否写寄存器的时序;
1:表示判断是否读寄存器的时序。

add_rw_cnt
内部信号
寄存器读写时序加一条件。
当处于寄存器配置状态并且下游sccb模块空闲,开始判断是否写/读寄存器的时序。
end_rw_cnt
内部信号
寄存器读写时序结束条件。
表示已经判断完是否写/读寄存器时序。


三、参考代码

下面展出本模块的设计,欢迎进一步交流,如果需要项目完整源代码,欢迎联系。
  1. module ov7670_config(

  2.      clk        ,

  3.      rst_n      ,

  4.      config_en  ,

  5.      rdy        ,

  6.      rdata      ,

  7.      rdata_vld  ,

  8.      wdata      ,

  9.      addr       ,

  10.      wr_en         ,

  11.         rd_en      ,

  12.      cmos_en    ,

  13.      pwdn        

  14.      );



  15.      parameter      DATA_W           8;

  16.      parameter      RW_NUM           2;

  17.      



  18.      input               clk         //50Mhz

  19.      input               rst_n    ;

  20.      input               config_en;

  21.      input               rdy      ;

  22.      input [DATA_W-1:0]  rdata    ;

  23.      input               rdata_vld;



  24.      output[DATA_W-1:0]  wdata    ;

  25.      output[DATA_W-1:0]  addr     ;

  26.      

  27.      output              cmos_en  ;

  28.      output              wr_en    ;

  29.      output              rd_en    ;

  30.      output              pwdn     ;

  31.      reg   [DATA_W-1:0]  wdata     ;

  32.      reg   [DATA_W-1:0]  addr      ;

  33.      reg                 cmos_en  ;

  34.      reg                 wr_en    ;

  35.      reg                 rd_en    ;



  36.      reg   [8 :0]        reg_cnt  ;

  37.      wire                 add_reg_cnt;

  38.      wire                 end_reg_cnt;

  39.      reg                  flag_add     ;

  40.      reg   [17:0]        add_wdata;



  41.      reg   [ 1:0]        rw_cnt     ;

  42.      wire                add_rw_cnt ;



  43.      assign              pwdn = 0;





  44.      `include "ov7670_para.v"

  45.                 

  46.                 

  47.      always  @(posedge clk or negedge  rst_n)begin

  48.          if(rst_n==1'b0)begin

  49.             reg_cnt <= 0;

  50.          end

  51.          else if(add_reg_cnt)begin

  52.             if(end_reg_cnt)

  53.                 reg_cnt <= 0;

  54.             else

  55.                 reg_cnt <= reg_cnt + 1;

  56.          end

  57.      end



  58.      assign add_reg_cnt = end_rw_cnt;    

  59.      assign end_reg_cnt = add_reg_cnt && reg_cnt==REG_NUM-1;



  60.      always  @(posedge clk or negedge  rst_n)begin

  61.          if(rst_n==1'b0)begin

  62.             rw_cnt <= 0;

  63.          end

  64.          else if(add_rw_cnt) begin

  65.             if(end_rw_cnt)

  66.                 rw_cnt <= 0;

  67.             else

  68.                 rw_cnt <= rw_cnt + 1;

  69.          end

  70.      end



  71.      assign  add_rw_cnt = flag_add  && rdy;

  72.      assign  end_rw_cnt = add_rw_cnt  && rw_cnt==RW_NUM-1;





  73.          

  74.      always  @(posedge clk or negedge  rst_n)begin

  75.          if(rst_n==1'b0)begin

  76.             flag_add <= 1'b0;

  77.          end

  78.          else if(config_en)begin

  79.             flag_add <= 1'b1;

  80.          end

  81.          else if(end_reg_cnt)begin

  82.             flag_add <= 1'b0;

  83.          end

  84.      end



  85.      //cmos_en

  86.      always  @(posedge clk or negedge  rst_n)begin

  87.          if(rst_n==1'b0)begin

  88.             cmos_en <= 1'b0;

  89.          end

  90.          else if(end_reg_cnt)begin

  91.             cmos_en <= 1'b1;

  92.          end

  93.      end





  94.      //add_wdata

  95.     

  96.      always  @(posedge clk or negedge  rst_n)begin

  97.          if(rst_n==1'b0)begin

  98.             wdata <= 8'b0;

  99.          end

  100.          else begin

  101.             wdata <= add_wdata[7:0];

  102.          end

  103.      end



  104.      always  @(posedge clk or negedge  rst_n)begin

  105.          if(rst_n==1'b0)begin

  106.             addr <= 8'b0;

  107.          end

  108.          else begin

  109.             addr <= add_wdata[15:8];

  110.          end

  111.      end





  112.      //wr_en

  113.      always  @(posedge clk or negedge  rst_n)begin

  114.          if(rst_n==1'b0)begin

  115.             wr_en <= 1'b0;

  116.          end

  117.          else if(add_rw_cnt && rw_cnt==0 && add_wdata[16])begin

  118.             wr_en <= 1'b1;

  119.          end

  120.          else begin

  121.             wr_en <= 1'b0;

  122.          end

  123.      end





  124.      always  @(posedge clk or negedge  rst_n)begin

  125.          if(rst_n==1'b0)begin

  126.             rd_en <= 1'b0;

  127.          end

  128.          else if(add_rw_cnt && rw_cnt==1 && add_wdata[17])begin

  129.             rd_en <= 1'b1;

  130.          end

  131.          else begin

  132.             rd_en <= 1'b0;

  133.          end

  134.      end

  135.        



  136. endmodule

0

阅读 评论 收藏 转载 喜欢 打印举报/Report
  • 评论加载中,请稍候...
发评论

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

      

    新浪BLOG意见反馈留言板 电话:4000520066 提示音后按1键(按当地市话标准计费) 欢迎批评指正

    新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

    新浪公司 版权所有