SCCB协议介绍与应用和OV7670摄像头的寄存器配置

SCCB协议简介:

以OV7670的配置传输为例

OV770中,8‘h42是写操作ID,8’h43是读地址
从数据传输时序可以看出,其传输的顺序是: 开始位,数据[7:0] ,X位,其中X位为任意,手册中给出的解释是don’t care
数据传输时序

开始传输时序:
3-wire Start of Data Transmission

SIO_D在SIO_C为高时由高到低表示开始传输。
即: SIO_C == 1 时,检测到SIO_D的下降沿就表示数据开始传输。

停止传输
当SIO_C == 1时,检测到SIO_D的上升沿表示结束位,即停止传输。

**

SCCB的三相写数据传输:

**
在这里插入图片描述
其中第一相,包括了7位ID地址、R/W选择位和X位。 //8’h42 写操作地址(OV7670)
第二项:要写的寄存器地址+X位
第三项:要写的数据+X位
写操作:三个阶段构成传输的写,每个阶段都为9位
即写操作有: start + ID地址(地址位42)+ 寄存器地址 + 数据 + stop

SCCB的读操作:

根据数据手册可知,读操作分为两个阶段完成
在这里插入图片描述
此阶段的目的是识别特定从设备的子地址,主设备从该子地址读取数据。
ID地址(8位ID地址+1位读写控制+don’t care)+ FPGA要向从机写入即将要读的寄存器地址(8位寄存器地址+don’t care)在这里插入图片描述
FPGA作为主机,在写入要读的寄存器地址后,从机(即OV7670)根据FPGA要读的地址将数据送给主机(FPGA).
ID地址(8位ID地址+1位读写控制+don’t care) +从机向FPGA发送被指定寄存器里面的数据的数据(8位数据+NA)
所以,写操作整体流程是:
起始位+ ID地址(42)+ 寄存器地址 +停止位+起始位+ID地址(43)+ 数据 + 结束位

SCCB协议有两线也有三线,两线为SIO_C与SIO_D,三线为SIO_E、SIO_C与SIO_D。

关于寄存器的调试步骤:
先读一个寄存器,确认读功能正确 -----> 写一个寄存器然后读出来,确认写功能正确-----> 所有寄存器写一个读一个,确保所有都正确--------> 全部致谢,快速进行配置。
首先,需要产生SCCB的时序,因为三相传输的数据一共有 1个起始位 +7ID+R/W+X + 8子地址+X+8写数据+X+结束位(0,1) = 30,故命名数组out_data作为三相和两相的拼接数组。

摄像头输入时钟为25MHz,而SCCB的SIO_C最高时钟频率是400KHz(注意:一般的器件,都是限制高速,而不会限制低速。速度越低,越容易满足时序参数要求。在调试时,尽量将速度放低,尽可能减少出错的可能。等数据调通后,再提高速度。)而本次使用的SIO_C频率为208KHz.

使用三个计数器分别计数一个SIO_C周期: (1s/208KHz) / (1s/25MHz) = 120
第二个计数 共有多少位SIO_D,根据读写的不同分别为30和21;
第三个计数器计数传输多少段,因为SCCB的读阶段是先由主机写子地址给从机,从机再去相应的地址将数据读出给主机,所以此处为2段。

计数器代码为:

   parameter      SIO_C  = 120 ; 

   always  @(posedge clk or negedge rst_n)begin
     if(rst_n==1'b0)begin
         flag_add <= 1'b0;
     end
     else if(ren || wen)begin  //有读使能或者写使能到来
         flag_add <= 1'b1;
     end
     else if(end_count_duan)begin  //传输完一整个读操作或者写操作
         flag_add <= 1'b0;
     end
 end

   always  @(posedge clk or negedge rst_n)begin
        if(rst_n==1'b0)begin
            count_sck <= 0;
        end
        else if(add_count_sck)begin
            if(end_count_sck)begin
                count_sck <= 0;
            end
            else begin
                count_sck <= count_sck + 1;
            end
        end
    end

    assign add_count_sck = flag_add;
    assign end_count_sck = add_count_sck && count_sck == SIO_C-1;
    
 //位传输计数器,由于写和读位数不同,所以此处采用变量法
 //bit_num+2表示所要计数的总位数  
 always @(posedge clk or negedge rst_n)begin 
     if(!rst_n)begin
         count_bit <= 0;
     end
     else if(add_count_bit)begin
         if(end_count_bit)
             count_bit <= 0;
         else
             count_bit <= count_bit + 1;
     end
 end

 assign add_count_bit = end_count_sck;
 assign end_count_bit = add_count_bit && count_bit == bit_num + 2 -1 ;
 
//由于写操作是三相零段,所以当 add_count_duan && count_duan == 1-1时结束计数
//写操作时:add_count_duan && count_duan == 1-1 为写操作
//写操作时:add_count_duan && count_duan == 2-1 为读操作
//使用变量来指示该计多少个数
 always @(posedge clk or negedge rst_n)begin
     if(!rst_n)begin
         count_duan <= 0;
     end
     else if(add_count_duan)begin
         if(end_count_duan)
             count_duan <= 0;
         else
             count_duan <= count_duan + 1;
     end
 end

 assign add_count_duan = end_count_bit;
 assign end_count_duan = add_count_duan && count_duan== section_num-1;

 //由于需要区分是写还是读,此处使用一个选择信号flag_sel
 //flag_sel == 1,表示是读状态
 //flag_sel == 2,表示是写状态
 always  @(posedge clk or negedge rst_n)begin
     if(rst_n==1'b0)begin
         flag_sel <= 0;
     end
     else if(ren)begin
         flag_sel <= 1;
     end
     else if(wen)begin
         flag_sel <= 2;
     end
	  else if(end_count_duan)begin
	      flag_sel <= 0;
	  end
 end


 always  @(*)begin
     if(flag_sel==1)begin
        bit_num     = 21; //读操作,两段两相
        section_num = 2 ;
     end
     else if(flag_sel==2)begin
         bit_num    = 30; //写操作,一段三相 
         section_num= 1 ;
     end
     else begin   
         bit_num     = 1;
         section_num = 1;
     end
 end

SCCB时序的产生:
上面计数器只是计数了周期数,对于SIO_C什么时候拉高拉低并无设计,占空比等也没有设计,此处对其进行约束。

always  @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
        sio_c <= 1'b1;
    end
    else if(sio_c_h2l)begin
        sio_c <= 1'b0;
    end
    else if(sio_c_l2h)begin
        sio_c <= 1'b1;
    end
end
//复位后若无拉高条件则SIO_C一直为高
assign   sio_c_h2l = count_bit >=0 && count_bit <(bit_num - 2) && add_count_sck && count_sck == SIO_C-1;//后面2bit不是数据传输过程,是结束位变化,此时SIO_C拉高,SIO_D在SIO_C为高期间由低变高表示结束位
assign   sio_c_l2h = count_bit >=1 && count_bit < bit_num && add_count_sck && count_sck == SIO_C/2 -1; //占空比50%,数据传输时使能

SIO_D数据的传输及本模块空闲信号设计

always  @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
        sio_d_w <= 1;
    end
    else if(out_data_time)begin
        sio_d_w <= out_data[30-count_bit-1];
    end
end 
//在SIO_C为低时且在其低位中部采样数据,以保证在SIO_C为高时数据稳定
assign  out_data_time = count_bit >= 0 && count_bit < bit_num && add_count_sck && count_sck == ((SIO_C/4) -1) ;

//有读或写使能以及数据在传输时,表示SCCB总线处理被占用
//rdy == 1表示SCCB空闲,可以处理新的数据
always  @(*)begin
    if(ren || wen || flag_sel != 0)begin
        rdy = 0;
    end
    else begin
        rdy = 1;
    end
end

//另设信号en_sio_d_w表示写操作  即无论是读还是写,写的部分都为其表示
//只有在读操作中的第二段第二相,向主机发送数据才读,故此阶段该信号拉低
//当执行完一个完整的读或者写操作时将其清零,该信号并不是必须只是本人设计需要,读者可自行改动
 //en_sio_d_w
 always  @(posedge clk or negedge rst_n)begin
     if(rst_n==1'b0)begin
         en_sio_d_w <= 1'b0;
     end
     else if(wen || ren)begin
         en_sio_d_w <= 1'b1;
     end
     else if(end_count_duan)begin
         en_sio_d_w <= 1'b0;
     end
     else if(en_sio_d_w_h2l)begin
         en_sio_d_w <= 1'b0;
     end
     else if(en_sio_d_w_l2h)begin
         en_sio_d_w <= 1'b1;
     end
 end


assign    en_sio_d_w_h2l = flag_sel == 1 && count_duan == 1 && count_bit==10 && add_count_sck && count_sck==1-1;
assign    en_sio_d_w_l2h = flag_sel == 1 && count_duan == 1 && count_bit==18 && add_count_sck && count_sck==1-1;

数据传输,使用数组out_data[29:0]来寄存传输总线上的信号。
写数据期间: 起始位,8‘h42,1’h1(X位),子地址,X位,要写的数据,X位,1‘b0,1’b1(结束位)

out_data = {1'h0,8'h42,1'h1,sub_addr,1'h1,wdata,1'h1,1'h0,1'h1};//sub_addr是SCCB总线上传输的数据,wdata是要写的数据

读数据期间:
第一段 : out_data = {1’h0,8’h42,1’h1,sub_addr,1’h1,1’h0,1’h1,9’h0};//后面9位并不会输出,只是为了对齐数据
第二段: out_data = {1’h0,8’h43,1’h1,sub_addr,1’h1,1’h0,1’h1,9’h0};
对比发现,可以整合为

 assign  rd_com = (count_duan==0 && flag_sel==1) ? 8'h42:8'h43;
 out_data = {1'h0,rd_com,1'h1,sub_addr,1'h1,1'h0,1'h1,9'h0};

所以发送数据的代码为:

always  @(*)begin
     if(flag_sel==1)begin
         out_data <= {1'h0,rd_com,1'h1,sub_addr,1'h1,1'h0,1'h1,9'h0};//start,8'h42 or 8'h43 ,x,sub_addr or rdata <= sio_d_r ,x,end(0,1) ,interval(2'b11)
     end
     else if(flag_sel==2)begin
         out_data <= {1'h0,8'h42,1'h1,sub_addr,1'h1,wdata,1'h1,1'h0,1'h1};
     end
     else begin
         out_data <= 0;
     end
 end

assign   rd_com = (count_duan==0 && flag_sel==1)? 8'h42 : 8'h43; //8'h42 is write enable | 8'h43 is read enable

OV7670寄存器配置

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date:    21:12:08 12/04/2018 
// Design Name: 
// Module Name:    ov7670_config 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//
module ov7670_config(
                     input             clk          ,  //25MHz
                     input             rst_n        ,
                     input             config_en    ,  //开始配置使能
                     input             rdy          ,  //上层模块空闲使能
                     input      [7:0]  rdata        ,  //SCCB输出的数据     本模块暂未使用,读者可以注释掉
                     input             rdata_vld    ,  //输出数据有效信号   本模块暂未使用,读者可以注释掉
                     output reg [7:0]  wdata        ,  
                     output reg [7:0]  addr         ,
                     output reg        wr_en        ,
                     output reg        rd_en        ,
                     output reg        cmos_en      ,   //
                     output            pwdn         
                     );

 
  parameter          DATA_WIDTH = 8 ;
  parameter          RW_NUM     = 2 ;

  reg      [DATA_WIDTH:0]      reg_cnt      ;      
  reg      [1:0]               rw_cnt       ;
  reg                          flag_add     ;
  wire                         add_reg_cnt  ;
  wire                         end_reg_cnt  ;
  wire                         add_rw_cnt   ;
  wire                         end_rw_cnt   ;
  reg      [17:0]              add_wdata    ;
 
 assign         pwdn = 0;

 `include "ov7670_para.v" //载入配置 该程序中包含了对OV7670的配置,程序在下文

 always @(posedge clk or negedge rst_n)begin
     if(!rst_n)begin
         rw_cnt <= 0;
     end
     else if(add_rw_cnt)begin
         if(end_rw_cnt)
             rw_cnt <= 0;
         else
             rw_cnt <= rw_cnt + 1;
     end
 end

 assign add_rw_cnt = flag_add && rdy ;
 assign end_rw_cnt = add_rw_cnt && rw_cnt==RW_NUM-1 ;

 always @(posedge clk or negedge rst_n)begin 
     if(!rst_n)begin
         reg_cnt <= 0;
     end
     else if(add_reg_cnt)begin
         if(end_reg_cnt)
             reg_cnt <= 0;
         else
             reg_cnt <= reg_cnt + 1;
     end
 end

 assign add_reg_cnt = end_rw_cnt;
 assign end_reg_cnt = add_reg_cnt && reg_cnt== REG_NUM - 1;

 always  @(posedge clk or negedge rst_n)begin
     if(rst_n==1'b0)begin
         flag_add <= 1'b0;
     end
     else if(config_en)begin
         flag_add <= 1'b1;
     end
     else if(end_reg_cnt)begin
         flag_add <= 1'b0;
     end
 end



 always  @(posedge clk or negedge rst_n)begin
     if(rst_n==1'b0)begin
         wdata <= 0;
     end
     else begin
         wdata <= add_wdata[7:0];
     end
 end

 always  @(posedge clk or negedge rst_n)begin
     if(rst_n==1'b0)begin
         addr <= 0;
     end
     else begin
         addr <= add_wdata[15:8];
     end
 end

 always  @(posedge clk or negedge rst_n)begin
     if(rst_n==1'b0)begin
         wr_en <= 1'b0;
     end
     else if(add_rw_cnt && rw_cnt==1-1 && add_wdata[16])begin
         wr_en <= 1'b1;
     end
     else begin
         wr_en <= 1'b0;
     end
 end

 always  @(posedge clk or negedge rst_n)begin
     if(rst_n==1'b0)begin
         rd_en <= 1'b0;
     end
     else if(add_rw_cnt && rw_cnt==2-1 && add_wdata[17])begin
         rd_en <= 1'b1;
     end
     else begin
         rd_en <= 1'b0;
     end
 end

 always  @(posedge clk or negedge rst_n)begin
     if(rst_n==1'b0)begin
         cmos_en <= 1'b0;
     end               
     else if(end_reg_cnt)begin
         cmos_en <= 1'b1;
     end
 end


endmodule

配置程序
具体的配置问题请参考器件手册《OV7670 Software Application Note》

parameter      REG_NUM =       165;
always@(*) begin
	    case(reg_cnt)
		     0   : add_wdata = {2'b11,16'h1204};//复位,VGA,RGB565 (00:YUV,04:RGB)(8x全局复位)
	        1   : add_wdata = {2'b11,16'h40d0};	//RGB565, 00-FF(d0)(YUV下要攱-FE(80))
	        2   : add_wdata = {2'b11,16'h3a04}; //TSLB(TSLB[3], COM13[0])00:YUYV, 01:YVYU, 10:UYVY(CbYCrY), 11:VYUY
	        3   : add_wdata = {2'b11,16'h3dc8};	//COM13(TSLB[3], COM13[0])00:YUYV, 01:YVYU, 10:UYVY(CbYCrY), 11:VYUY
	        4   : add_wdata = {2'b11,16'h1e31};	//默认01,Bit[5]水平镜像,Bit[4]竖直镜像
	        5   : add_wdata = {2'b11,16'h6b00};	//旁路PLL倍频ク0A:关闭内部LDOク00:打开LDO
	        6   : add_wdata = {2'b11,16'h32b6};	//HREF 控制(80)
	        7   : add_wdata = {2'b11,16'h1713};	//HSTART 输出格式-行频开始高8位
	        8   : add_wdata = {2'b11,16'h1801};	//HSTOP  输出格式-行频结束
	        9   : add_wdata = {2'b11,16'h1902};	//VSTART 输出格式-场频开始高8位
	        10  : add_wdata = {2'b11,16'h1a7a};	//VSTOP  输出格式-场频结束
	        11  : add_wdata = {2'b11,16'h030a};	//VREF	 帧竖直方向控到0)
	        12  : add_wdata = {2'b11,16'h0c00};	//DCW使能 禁止(00)
	        13  : add_wdata = {2'b11,16'h3e10};	//PCLK分频00 Normal  14  : add_wdata = {2'b11,16'h7000};	//00:Normal, 80:移位1, 00:彩条, 80:渐变彩条
	        15  : add_wdata = {2'b11,16'h7100};	//00:Normal, 00:移位1, 80:彩条, 80:渐变彩杊	        16  : add_wdata = {2'b11,16'h7211};	//默认 水平,垂直采样(11)	        
	        17  : add_wdata = {2'b11,16'h7300};	//DSP缩放时钟分频00 
	        18  : add_wdata = {2'b11,16'ha202};	//默认 像素始终延迟	(02)
	        19  : add_wdata = {2'b11,16'h1180};	//内部工作时钟设置,直接使用外部时钟源(80)
	        20  : add_wdata = {2'b11,16'h7a20};
	        21  : add_wdata = {2'b11,16'h7b1c};
	        22  : add_wdata = {2'b11,16'h7c28};
	        23  : add_wdata = {2'b11,16'h7d3c};
	        24  : add_wdata = {2'b11,16'h7e55};
	        25  : add_wdata = {2'b11,16'h7f68};
	        26  : add_wdata = {2'b11,16'h8076};
	        27  : add_wdata = {2'b11,16'h8180};
	        28  : add_wdata = {2'b11,16'h8288};
	        29  : add_wdata = {2'b11,16'h838f};
	        30  : add_wdata = {2'b11,16'h8496};
	        31  : add_wdata = {2'b11,16'h85a3};
	        32  : add_wdata = {2'b11,16'h86af};
	        33  : add_wdata = {2'b11,16'h87c4};
	        34  : add_wdata = {2'b11,16'h88d7};
	        35  : add_wdata = {2'b11,16'h89e8};
	        36  : add_wdata = {2'b11,16'h13e0};
	        37  : add_wdata = {2'b11,16'h0010};//
	        38  : add_wdata = {2'b11,16'h1000};
	        39  : add_wdata = {2'b11,16'h0d00};
	        40  : add_wdata = {2'b11,16'h1428}; 
	        41  : add_wdata = {2'b11,16'ha505};
	        42  : add_wdata = {2'b11,16'hab07};
	        43  : add_wdata = {2'b11,16'h2475};
	        44  : add_wdata = {2'b11,16'h2563};
	        45  : add_wdata = {2'b11,16'h26a5};
	        46  : add_wdata = {2'b11,16'h9f78};
	        47  : add_wdata = {2'b11,16'ha068};
	        48  : add_wdata = {2'b11,16'ha103};
	        49  : add_wdata = {2'b11,16'ha6df};
	        50  : add_wdata = {2'b11,16'ha7df};
	        51  : add_wdata = {2'b11,16'ha8f0};
	        52  : add_wdata = {2'b11,16'ha990};
	        53  : add_wdata = {2'b11,16'haa94};
	        54  : add_wdata = {2'b11,16'h13ef};  
	        55  : add_wdata = {2'b11,16'h0e61};
	        56  : add_wdata = {2'b11,16'h0f4b};
	        57  : add_wdata = {2'b11,16'h1602};
	        58  : add_wdata = {2'b11,16'h2102};
	        59  : add_wdata = {2'b11,16'h2291};
	        60  : add_wdata = {2'b11,16'h2907};
	        61  : add_wdata = {2'b11,16'h330b};
	        62  : add_wdata = {2'b11,16'h350b};
	        63  : add_wdata = {2'b11,16'h371d};
	        64  : add_wdata = {2'b11,16'h3871};
	        65  : add_wdata = {2'b11,16'h392a};
	        66  : add_wdata = {2'b11,16'h3c78};
	        67  : add_wdata = {2'b11,16'h4d40};
	        68  : add_wdata = {2'b11,16'h4e20};
	        69  : add_wdata = {2'b11,16'h6900};
	        
	        70  : add_wdata = {2'b11,16'h7419};
	        71  : add_wdata = {2'b11,16'h8d4f};
	        72  : add_wdata = {2'b11,16'h8e00};
	        73  : add_wdata = {2'b11,16'h8f00};
	        74  : add_wdata = {2'b11,16'h9000};
	        75  : add_wdata = {2'b11,16'h9100};
	        76  : add_wdata = {2'b11,16'h9200};
	        77  : add_wdata = {2'b11,16'h9600};
	        78  : add_wdata = {2'b11,16'h9a80};
	        79  : add_wdata = {2'b11,16'hb084};
	        80  : add_wdata = {2'b11,16'hb10c};
	        81  : add_wdata = {2'b11,16'hb20e};
	        82  : add_wdata = {2'b11,16'hb382};
	        83  : add_wdata = {2'b11,16'hb80a};

	        84  : add_wdata = {2'b11,16'h4314};
	        85  : add_wdata = {2'b11,16'h44f0};
	        86  : add_wdata = {2'b11,16'h4534};
	        87  : add_wdata = {2'b11,16'h4658};
	        88  : add_wdata = {2'b11,16'h4728};
	        89  : add_wdata = {2'b11,16'h483a};
	        90  : add_wdata = {2'b11,16'h5988};
	        91  : add_wdata = {2'b11,16'h5a88};
	        92  : add_wdata = {2'b11,16'h5b44};
	        93  : add_wdata = {2'b11,16'h5c67};
	        94  : add_wdata = {2'b11,16'h5d49};
	        95  : add_wdata = {2'b11,16'h5e0e};
	        96  : add_wdata = {2'b11,16'h6404};
	        97  : add_wdata = {2'b11,16'h6520};
	        98  : add_wdata = {2'b11,16'h6605};
	        99  : add_wdata = {2'b11,16'h9404};
	        100 : add_wdata = {2'b11,16'h9508};
	        101 : add_wdata = {2'b11,16'h6c0a};
	        102 : add_wdata = {2'b11,16'h6d55};
	        103 : add_wdata = {2'b11,16'h6e11};
	        104 : add_wdata = {2'b11,16'h6f9f};
	        105 : add_wdata = {2'b11,16'h6a40};
	        106 : add_wdata = {2'b11,16'h0140};
	        107 : add_wdata = {2'b11,16'h0240};
	        108 : add_wdata = {2'b11,16'h13e7};
	        109 : add_wdata = {2'b11,16'h1500};
	        
	        110 : add_wdata = {2'b11,16'h4f80};
	        111 : add_wdata = {2'b11,16'h5080};
	        112 : add_wdata = {2'b11,16'h5100};
	        113 : add_wdata = {2'b11,16'h5222};
	        114 : add_wdata = {2'b11,16'h535e};
	        115 : add_wdata = {2'b11,16'h5480};
	        116 : add_wdata = {2'b11,16'h589e};
	        
	        117 : add_wdata = {2'b11,16'h4108};
	        118 : add_wdata = {2'b11,16'h3f00};
	        119 : add_wdata = {2'b11,16'h7505};
	        120 : add_wdata = {2'b11,16'h76e1};
	        121 : add_wdata = {2'b11,16'h4c00};
	        122 : add_wdata = {2'b11,16'h7701};
	        
	        123 : add_wdata = {2'b11,16'h4b09};
	        124 : add_wdata = {2'b11,16'hc9F0};//16'hc960;
	        125 : add_wdata = {2'b11,16'h4138};
	        126 : add_wdata = {2'b11,16'h5640};
	        
	        
	        127 : add_wdata = {2'b11,16'h3411};
	        128 : add_wdata = {2'b11,16'h3b02};
	        129 : add_wdata = {2'b11,16'ha489};
	        130 : add_wdata = {2'b11,16'h9600};
	        131 : add_wdata = {2'b11,16'h9730};
	        132 : add_wdata = {2'b11,16'h9820};
	        133 : add_wdata = {2'b11,16'h9930};
	        134 : add_wdata = {2'b11,16'h9a84};
	        135 : add_wdata = {2'b11,16'h9b29};
	        136 : add_wdata = {2'b11,16'h9c03};
	        137 : add_wdata = {2'b11,16'h9d4c};
	        138 : add_wdata = {2'b11,16'h9e3f};
	        139 : add_wdata = {2'b11,16'h7804};
	        
	        
	         140 :add_wdata =  {2'b11,16'h7901};
	         141 :add_wdata =  {2'b11,16'hc8f0};
	         142 :add_wdata =  {2'b11,16'h790f};
	         143 :add_wdata =  {2'b11,16'hc800};
	         144 :add_wdata =  {2'b11,16'h7910};
	         145 :add_wdata =  {2'b11,16'hc87e};
	         146 :add_wdata =  {2'b11,16'h790a};
	         147 :add_wdata =  {2'b11,16'hc880};
	         148 :add_wdata =  {2'b11,16'h790b};
	         149 :add_wdata =  {2'b11,16'hc801};
	         150 :add_wdata =  {2'b11,16'h790c};
	         151 :add_wdata =  {2'b11,16'hc80f};
	         152 :add_wdata =  {2'b11,16'h790d};
	         153 :add_wdata =  {2'b11,16'hc820};
	         154 :add_wdata =  {2'b11,16'h7909};
	         155 :add_wdata =  {2'b11,16'hc880};
	         156 :add_wdata =  {2'b11,16'h7902};
	         157 :add_wdata =  {2'b11,16'hc8c0};
	         158 :add_wdata =  {2'b11,16'h7903};
	         159 :add_wdata =  {2'b11,16'hc840};
	         160 :add_wdata =  {2'b11,16'h7905};
	         161 :add_wdata =  {2'b11,16'hc830}; 
	         162 :add_wdata =  {2'b11,16'h7926};
	         
	         163 : add_wdata = {2'b11,16'h0903};
	         164 : add_wdata = {2'b11,16'h3b42};
		
	    default : add_wdata = 0;
	    endcase
	end

//产生时序时,除了readdata外,都要打开三态门。而在空闲时刻,要注意将三态门关闭。
即写操作的全部阶段,读操作的第一阶段和第二阶段的第一相打开,在空闲和读操作的第二阶段关闭。

  • 7
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、SCCB协议简述 SCCB协议有两线也有三线,两线为SIO_C与SIO_D,三线为SIO_E、SIO_C与SIO_D。 2线的SCCB总线只能是一个主器件对一个从器件控制,但3线SCCB接口可以对多个从器件控制,因此当只有一个从机(slave device)时用两线,有多个从机时用三线。 其中SIO_C只能由主机配置FPGA),SIO_D是一个三态门,双向数据线,既可以由主机控制,也可以由从机控制。 2、数据传输 当写数据到从机被定义为写传输(write transmission),当从机中读数据被定义为读传输 (read transmission),每一个传输都要有开始和结束来释放总线(start + sotp) 完整的数据传输包括两个或三个阶段,每一个阶段包含9位数据,其中高8位为所要传输的数据,最低位根据器件所处情况有不同的取值: 总结如下: 每一个阶段组成:8位数据+don't care/NA 如果是主机发送数据,即进行写操作,第九位就为don't care 如果是从机发送数据,即为读操作,第九位就为NA. 在进行主器件写操作时,全部阶段的最低位均是Don’t care bit 在进行主器件读操作时,第一阶段的最低位是自由位,第二阶段的最低位为NA,请结合第三部分好好理解 3、SCCB的读写操作 写操作是三个阶段构成一个传输的写,每一阶段都是9位,具体如下 ID地址(7位ID地址+1位读写控制+don't care) + 要写的寄存器地址(8位寄存器地址+don't care) +要写入的数据(8位数据+don't care) 要强调的是ID地址,写为8'h42,读为8'h42 , 8'h42即ID地址的读写控制位为0,8'h43即ID地址的读写控制位为1 总结为: start + ID地址(42)+ 寄存器地址 + 数据 + stop

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值