MyFPGA Forum

 找回密码
 注册
搜索
查看: 7719|回复: 7
打印 上一主题 下一主题

发现DE2 IIC写寄存器的问题

[复制链接]
跳转到指定楼层
1#
发表于 2010-3-2 10:44:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
根据美光sensor寄存器读写操作要求,IIC必须在时钟跳变时将数据写入寄存器,但是程序看不到Sclk的跳变,而只有Sdata的写入,这个总线如何能工作

代码:
// --------------------------------------------------------------------
// Copyright (c) 2005 by Terasic Technologies Inc.
// --------------------------------------------------------------------
//
// Permission:
//
//   Terasic grants permission to use and modify this code for use
//   in synthesis for all Terasic Development Boards and Altrea Development
//   Kits made by Terasic.  Other use of this code, including the selling
//   ,duplication, or modification of any portion is strictly prohibited.
//
// Disclaimer:
//
//   This VHDL or Verilog source code is intended as a design reference
//   which illustrates how these types of functions can be implemented.
//   It is the user's responsibility to verify their design for
//   consistency and functionality through the use of formal
//   verification methods.  Terasic provides no warranty regarding the use
//   or functionality of this code.
//
// --------------------------------------------------------------------
//           
//                     Terasic Technologies Inc
//                     356 Fu-Shin E. Rd Sec. 1. JhuBei City,
//                     HsinChu County, Taiwan
//                     302
//
//                     web: http://www.terasic.com/
//                     email: support@terasic.com
//
// --------------------------------------------------------------------
//
// Major Functions:i2c controller
//
// --------------------------------------------------------------------
//
// Revision History :
// --------------------------------------------------------------------
//   Ver  :| Author            :| Mod. Date :| Changes Made:
//   V1.0 :| Joe Yang          :| 05/07/10  :|      Initial Revision
// --------------------------------------------------------------------
module I2C_Controller (
        CLOCK,
        I2C_SCLK,//I2C CLOCK
        I2C_SDAT,//I2C DATA
        I2C_DATA,//DATA:[SLAVE_ADDR,SUB_ADDR,DATA]
        GO,      //GO transfor
        END,     //END transfor
        W_R,     //W_R
        ACK,      //ACK
        RESET,
        //TEST
        SD_COUNTER,
        SDO
);
        input  CLOCK;
        input  [23:0]I2C_DATA;       
        input  GO;
        input  RESET;       
        input  W_R;
        inout  I2C_SDAT;       
        output I2C_SCLK;
        output END;       
        output ACK;

//TEST
        output [5:0] SD_COUNTER;
        output SDO;


reg SDO;
reg SCLK;
reg END;
reg [23:0]SD;
reg [5:0]SD_COUNTER;

wire I2C_SCLK=SCLK | ( ((SD_COUNTER >= 4) & (SD_COUNTER <=30))? ~CLOCK :0 );
wire I2C_SDAT=SDO?1'bz:0 ;

reg ACK1,ACK2,ACK3;
wire ACK=ACK1 | ACK2 |ACK3;

//--I2C COUNTER
always @(negedge RESET or posedge CLOCK ) begin
if (!RESET) SD_COUNTER=6'b111111;
else begin
if (GO==0)
        SD_COUNTER=0;
        else
        if (SD_COUNTER < 6'b111111) SD_COUNTER=SD_COUNTER+1;       
end
end
//----

always @(negedge RESET or  posedge CLOCK ) begin
if (!RESET) begin SCLK=1;SDO=1; ACK1=0;ACK2=0;ACK3=0; END=1; end
else
case (SD_COUNTER)
        6'd0  : begin ACK1=0 ;ACK2=0 ;ACK3=0 ; END=0; SDO=1; SCLK=1;end
        //start
        6'd1  : begin SD=I2C_DATA;SDO=0;end
        6'd2  : SCLK=0;
        //SLAVE ADDR
        6'd3  : SDO=SD[23];
        6'd4  : SDO=SD[22];
        6'd5  : SDO=SD[21];
        6'd6  : SDO=SD[20];
        6'd7  : SDO=SD[19];
        6'd8  : SDO=SD[18];
        6'd9  : SDO=SD[17];
        6'd10 : SDO=SD[16];       
        6'd11 : SDO=1'b1;//ACK

        //SUB ADDR
        6'd12  : begin SDO=SD[15]; ACK1=I2C_SDAT; end
        6'd13  : SDO=SD[14];
        6'd14  : SDO=SD[13];
        6'd15  : SDO=SD[12];
        6'd16  : SDO=SD[11];
        6'd17  : SDO=SD[10];
        6'd18  : SDO=SD[9];
        6'd19  : SDO=SD[8];
        6'd20  : SDO=1'b1;//ACK

        //DATA
        6'd21  : begin SDO=SD[7]; ACK2=I2C_SDAT; end
        6'd22  : SDO=SD[6];
        6'd23  : SDO=SD[5];
        6'd24  : SDO=SD[4];
        6'd25  : SDO=SD[3];
        6'd26  : SDO=SD[2];
        6'd27  : SDO=SD[1];
        6'd28  : SDO=SD[0];
        6'd29  : SDO=1'b1;//ACK

       
        //stop
    6'd30 : begin SDO=1'b0;        SCLK=1'b0; ACK3=I2C_SDAT; end       
    6'd31 : SCLK=1'b1;
    6'd32 : begin SDO=1'b1; END=1; end

endcase
end



endmodule
2#
发表于 2010-3-3 11:43:01 | 只看该作者
本帖最后由 Pocahontas 于 2010-3-3 11:45 编辑

在读写数据的区间

wire I2C_SCLK=SCLK | ( ((SD_COUNTER >= 4) & (SD_COUNTER <=30))? ~CLOCK :0 );

Sclk是会跳变的,  所以这个程序看起来是没有问题的
3#
发表于 2010-3-3 17:13:25 | 只看该作者
你有用 signal tap 抓出来看吗??? 看看是否真的没跳变
4#
发表于 2010-7-21 16:53:21 | 只看该作者
6'd11 : SDO=1'b1;//ACK

        //SUB ADDR
        6'd12  : begin SDO=SD[15]; ACK1=I2C_SDAT; end
可否麻烦高手解释下,i2c时序不是要求在数据第8位发完后,下一个sclk 时钟到来时,sdat即为响应位。但是从这个时序看,8位数据的下一时钟到来是把sdat 线拉高阻。在等一个时钟才发出响应啊.这个怎么回事?
5#
发表于 2010-7-27 00:30:53 | 只看该作者
6'd11 : SDO<=1'b1; // 保留给受控器回应
        6'd12  : begin SDO<=SD[15]; ACK1<=I2C_SDAT; end // 储存接受到的响应
                                                                                                                                      //(对装置地址)
:$
6#
发表于 2011-11-23 00:32:13 | 只看该作者
支持一下吧!最近的鸭梨好大啊
7#
发表于 2011-12-1 08:12:01 | 只看该作者
希望大家踊跃发言,我顶先
8#
发表于 2012-5-18 10:14:44 | 只看该作者
新手报到,请多多关照。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|MyFPGA

GMT+8, 2024-5-6 23:10 , Processed in 0.043292 second(s), 17 queries .

Powered by Discuz! X3

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表