精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

一文帶你迅速了解常用串行總線之IIC協議2

jf_78858299 ? 來源:Cascatrix ? 作者:Carson ? 2023-01-21 17:20 ? 次閱讀

2. 組幀模塊 (i2c_ctrl):

module i2c_ctrl

(

input rst,

input clk,

input[15:0] clk_div_cnt,

// I2C signals

// i2c clock line

input scl_pad_i, //SCL-line input

output scl_pad_o, //SCL-line output (always 1'b0)

output scl_padoen_o, //SCL-line output enable (active low)

// i2c data line

input sda_pad_i, //SDA-line input

output sda_pad_o, //SDA-line output (always 1'b0)

output sda_padoen_o, //SDA-line output enable (active low)

input i2c_addr_2byte, //register address 16bit or 8bit

input i2c_read_req, //Read register request

output i2c_read_req_ack, //Read register request response

input i2c_write_req, //Write register request

output i2c_write_req_ack, //Write register request response

input[7:0] i2c_slave_dev_addr, //I2c device address

input[15:0] i2c_slave_reg_addr, //I2c register address

input[7:0] i2c_write_data, //I2c write register data

output reg[7:0] i2c_read_data,//I2c read register data

output reg error //The error indication, generally there is no response

);

//State machine definition cascatrix carson

localparam S_IDLE= 0;

localparam S_WR_DEV_ADDR=1;

localparam S_WR_REG_ADDR=2;

localparam S_WR_DATA=3;

localparam S_WR_ACK=4;

localparam S_WR_ERR_NACK=5;

localparam S_RD_DEV_ADDR0=6;

localparam S_RD_REG_ADDR=7;

localparam S_RD_DEV_ADDR1=8;

localparam S_RD_DATA=9;

localparam S_RD_STOP=10;

localparam S_WR_STOP=11;

localparam S_WAIT=12;

localparam S_WR_REG_ADDR1=13;

localparam S_RD_REG_ADDR1=14;

localparam S_RD_ACK=15;

reg start;

reg stop;

reg read;

reg write;

reg ack_in;

reg[7:0] txr;

wire[7:0] rxr;

wire i2c_busy;

wire i2c_al;

wire done;

wire irxack;

reg[3:0] state, next_state;

assign i2c_read_req_ack = (state == S_RD_ACK);

assign i2c_write_req_ack = (state == S_WR_ACK);

always@(posedge clk or posedge rst)

begin

if(rst)

    state <= S_IDLE;

else

    state <= next_state;

end

always@(*)

begin

case(state)

S_IDLE:

//Waiting for read and write requests

    if(i2c_write_req)

        next_state <= S_WR_DEV_ADDR;

    else if(i2c_read_req)

        next_state <= S_RD_DEV_ADDR0;

    else

        next_state <= S_IDLE;

//Write I2C device address

S_WR_DEV_ADDR:

    if(done && irxack)

        next_state <= S_WR_ERR_NACK;

    else if(done)

        next_state <= S_WR_REG_ADDR;

    else

        next_state <= S_WR_DEV_ADDR;

//Write the address of the I2C register

S_WR_REG_ADDR:

    if(done)

//If it is the 8bit register address, it enters the write data state

    next_state<=i2c_addr_2byte? S_WR_REG_AD DR1  : S_WR_DATA;

    else

        next_state <= S_WR_REG_ADDR;

S_WR_REG_ADDR1:

    if(done)

        next_state <= S_WR_DATA;

    else

        next_state <= S_WR_REG_ADDR1; 

//Write data

S_WR_DATA:

    if(done)

        next_state <= S_WR_STOP;

    else

        next_state <= S_WR_DATA;

S_WR_ERR_NACK:

    next_state <= S_WR_STOP;

S_RD_ACK,S_WR_ACK:

    next_state <= S_WAIT;

S_WAIT:

    next_state <= S_IDLE;

S_RD_DEV_ADDR0:

    if(done && irxack)

        next_state <= S_WR_ERR_NACK;

    else if(done)

        next_state <= S_RD_REG_ADDR;

    else

        next_state <= S_RD_DEV_ADDR0;

S_RD_REG_ADDR:

    if(done)

    next_state<=i2c_addr_2byte?S_RD_REG_ADDR1 : S_RD_DEV_ADDR1;

    else

        next_state <= S_RD_REG_ADDR;

S_RD_REG_ADDR1:

    if(done)

        next_state <= S_RD_DEV_ADDR1;

    else

        next_state <= S_RD_REG_ADDR1;               

S_RD_DEV_ADDR1:

    if(done)

        next_state <= S_RD_DATA;

    else

        next_state <= S_RD_DEV_ADDR1;   

S_RD_DATA:

    if(done)

        next_state <= S_RD_STOP;

    else

        next_state <= S_RD_DATA;

S_RD_STOP:

    if(done)

        next_state <= S_RD_ACK;

    else

        next_state <= S_RD_STOP;

S_WR_STOP:

    if(done)

        next_state <= S_WR_ACK;

    else

        next_state <= S_WR_STOP;                

default:

    next_state <= S_IDLE;

endcase

end

always@(posedge clk or posedge rst)

begin

if(rst)

    error <= 1'b0;

else if(state == S_IDLE)

    error <= 1'b0;

else if(state == S_WR_ERR_NACK)

    error <= 1'b1;

end

always@(posedge clk or posedge rst)

begin

if(rst)

    start <= 1'b0;

else if(done)

    start <= 1'b0;

else if(state == S_WR_DEV_ADDR || state == S_RD_DEV_ADDR0 || state == S_RD_DEV_ADDR1)

start <= 1'b1;

end

always@(posedge clk or posedge rst)

begin

if(rst)

    stop <= 1'b0;

else if(done)

    stop <= 1'b0;

else if(state == S_WR_STOP || state == S_RD_STOP)

    stop <= 1'b1;

end

always@(posedge clk or posedge rst)

begin

if(rst)

    ack_in <= 1'b0;

else 

    ack_in <= 1'b1;

end

always@(posedge clk or posedge rst)

begin

if(rst)

    write <= 1'b0;

else if(done)

    write <= 1'b0;

else if(state == S_WR_DEV_ADDR || state == S_WR_REG_ADDR || state == S_WR_REG_ADDR1|| state == S_WR_DATA || state == S_RD_DEV_ADDR0 || state == S_RD_DEV_ADDR1 || state == S_RD_REG_ADDR || state == S_RD_REG_ADDR1)

write <= 1'b1;

end

always@(posedge clk or posedge rst)

begin

if(rst)

    read <= 1'b0;

else if(done)

    read <= 1'b0;

else if(state == S_RD_DATA)

    read <= 1'b1;

end

always@(posedge clk or posedge rst)

begin

if(rst)

    i2c_read_data <= 8'h00;

else if(state == S_RD_DATA && done)

    i2c_read_data <= rxr;

end

always@(posedge clk or posedge rst)

begin

if(rst)

    txr <= 8'd0;

else 

case(state)

S_WR_DEV_ADDR,S_RD_DEV_ADDR0:

    txr <= {i2c_slave_dev_addr[7:1],1'b0};

S_RD_DEV_ADDR1:

    txr <= {i2c_slave_dev_addr[7:1],1'b1};

S_WR_REG_ADDR,S_RD_REG_ADDR:

txr<=(i2c_addr_2byte==1'b1)?i2c_slave_reg_addr[15 :8] : i2c_slave_reg_addr[7:0];

S_WR_REG_ADDR1,S_RD_REG_ADDR1:

    txr <= i2c_slave_reg_addr[7:0];             

S_WR_DATA:

    txr <= i2c_write_data;

default:

    txr <= 8'hff;

endcase

end

i2c_byte_ctrl byte_controller (

.clk ( clk ),

.rst ( rst ),

.nReset ( 1'b1 ),

.ena ( 1'b1 ),

.clk_cnt ( clk_div_cnt ),

.start ( start ),

.stop ( stop ),

.read ( read ),

.write ( write ),

.ack_in ( ack_in ),

.din ( txr ),

.cmd_ack ( done ),

.ack_out ( irxack ),

.dout ( rxr ),

.i2c_busy ( i2c_busy ),

.i2c_al ( i2c_al ),

.scl_i ( scl_pad_i ),

.scl_o ( scl_pad_o ),

.scl_oen ( scl_padoen_o ),

.sda_i ( sda_pad_i ),

.sda_o ( sda_pad_o ),

.sda_oen ( sda_padoen_o )

);

endmodule

3. 字節控制模塊(i2c_byte_ctrl):

`define I2C_CMD_NOP 4'b0000

`define I2C_CMD_START 4'b0001

`define I2C_CMD_STOP 4'b0010

`define I2C_CMD_WRITE 4'b0100

`define I2C_CMD_READ 4'b1000

module i2c_byte_ctrl (

input clk, // master clock

input rst, // synchronous active high reset

input nReset, // asynchronous active low reset

input ena, // core enable signal

input [15:0] clk_cnt, // 4x SCL

// control inputs

input start,

input stop,

input read,

input write,

input ack_in,

input [7:0] din,

// status outputs

output reg cmd_ack,

output reg ack_out,

output i2c_busy,

output i2c_al,

output [7:0] dout,

// I2C signals

input scl_i,

output scl_o,

output scl_oen,

input sda_i,

output sda_o,

output sda_oen

);

//

// Variable declarations cascatrix carson

//

// statemachine

parameter [4:0] ST_IDLE = 5'b0_0000;

parameter [4:0] ST_START = 5'b0_0001;

parameter [4:0] ST_READ = 5'b0_0010;

parameter [4:0] ST_WRITE = 5'b0_0100;

parameter [4:0] ST_ACK = 5'b0_1000;

parameter [4:0] ST_STOP = 5'b1_0000;

// signals for bit_controller

reg [3:0] core_cmd;

reg core_txd;

wire core_ack, core_rxd;

// signals for shift register

reg [7:0] sr; //8bit shift register

reg shift, ld;

// signals for state machine

wire go;

reg [2:0] dcnt;

wire cnt_done;

// bit_controller

i2c_bit_ctrl bit_controller (

.clk ( clk ),

.rst ( rst ),

.nReset ( nReset ),

.ena ( ena ),

.clk_cnt ( clk_cnt ),

.cmd ( core_cmd ),

.cmd_ack ( core_ack ),

.busy ( i2c_busy ),

.al ( i2c_al ),

.din ( core_txd ),

.dout ( core_rxd ),

.scl_i ( scl_i ),

.scl_o ( scl_o ),

.scl_oen ( scl_oen ),

.sda_i ( sda_i ),

.sda_o ( sda_o ),

.sda_oen ( sda_oen )

);

// generate go-signal

assign go = (read | write | stop) & ~cmd_ack;

// assign dout output to shift-register

assign dout = sr;

// generate shift register

always @(posedge clk or negedge nReset)

if (!nReset)

sr <= #1 8'h0;

else if (rst)

sr <= #1 8'h0;

else if (ld)

sr <= #1 din;

else if (shift)

sr <= #1 {sr[6:0], core_rxd};

// generate counter

always @(posedge clk or negedge nReset)

if (!nReset)

dcnt <= #1 3'h0;

else if (rst)

dcnt <= #1 3'h0;

else if (ld)

dcnt <= #1 3'h7;

else if (shift)

dcnt <= #1 dcnt - 3'h1;

assign cnt_done = ~(|dcnt);

//

// state machine

//

reg [4:0] c_state; // synopsys enum_state

always @(posedge clk or negedge nReset)

if (!nReset)

begin

    core_cmd <= #1 `I2C_CMD_NOP;

    core_txd <= #1 1'b0;

    shift    <= #1 1'b0;

    ld       <= #1 1'b0;

    cmd_ack  <= #1 1'b0;

    c_state  <= #1 ST_IDLE;

    ack_out  <= #1 1'b0;

end

else if (rst | i2c_al)

begin

core_cmd <= #1 `I2C_CMD_NOP;

   core_txd <= #1 1'b0;

   shift    <= #1 1'b0;

   ld       <= #1 1'b0;

   cmd_ack  <= #1 1'b0;

   c_state  <= #1 ST_IDLE;

   ack_out  <= #1 1'b0;

end

else

begin

// initially reset all signals

  core_txd <= #1 sr[7];

  shift    <= #1 1'b0;

  ld       <= #1 1'b0;

  cmd_ack  <= #1 1'b0;

  case (c_state) // synopsys full_case parallel_case

    ST_IDLE:

      if (go)

        begin

            if (start)

              begin

                  c_state  <= #1 ST_START;

                  core_cmd <= #1 `I2C_CMD_START;

              end

            else if (read)

              begin

                  c_state  <= #1 ST_READ;

                  core_cmd <= #1 `I2C_CMD_READ;

              end

            else if (write)

              begin

                  c_state  <= #1 ST_WRITE;

                  core_cmd <= #1 `I2C_CMD_WRITE;

              end

            else // stop

              begin

                  c_state  <= #1 ST_STOP;

                  core_cmd <= #1 `I2C_CMD_STOP;

              end

            ld <= #1 1'b1;

        end

    ST_START:

      if (core_ack)

        begin

            if (read)

              begin

                  c_state  <= #1 ST_READ;

                  core_cmd <= #1 `I2C_CMD_READ;

              end

            else

              begin

                  c_state  <= #1 ST_WRITE;

                  core_cmd <= #1 `I2C_CMD_WRITE;

              end

            ld <= #1 1'b1;

        end

    ST_WRITE:

      if (core_ack)

        if (cnt_done)

          begin

              c_state  <= #1 ST_ACK;

              core_cmd <= #1 `I2C_CMD_READ;

          end

        else

          begin

                // stay in same state

              c_state  <= #1 ST_WRITE;       

                // write next bit

              core_cmd <= #1 `I2C_CMD_WRITE; 

              shift    <= #1 1'b1;

          end

    ST_READ:

      if (core_ack)

        begin

            if (cnt_done)

              begin

                  c_state  <= #1 ST_ACK;

                  core_cmd <= #1 `I2C_CMD_WRITE;

              end

            else

              begin

                    // stay in same state

                  c_state  <= #1 ST_READ;       

                     // read next bit

                  core_cmd <= #1 `I2C_CMD_READ;

              end

            shift    <= #1 1'b1;

            core_txd <= #1 ack_in;

        end

    ST_ACK:

      if (core_ack)

        begin

           if (stop)

             begin

                 c_state  <= #1 ST_STOP;

                 core_cmd <= #1 `I2C_CMD_STOP;

             end

           else

             begin

                 c_state  <= #1 ST_IDLE;

                 core_cmd <= #1 `I2C_CMD_NOP;

                 // generate command acknowledge signal

                 cmd_ack  <= #1 1'b1;

             end

             // assign ack_out output to bit_controller_rxd (contains last received bit)

             ack_out <= #1 core_rxd;

             core_txd <= #1 1'b1;

         end

       else

         core_txd <= #1 ack_in;

    ST_STOP:

      if (core_ack)

        begin

            c_state  <= #1 ST_IDLE;

            core_cmd <= #1 `I2C_CMD_NOP;

            // generate command acknowledge signal

            cmd_ack  <= #1 1'b1;

        end

  endcase

end

endmodule

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • IIC
    IIC
    +關注

    關注

    11

    文章

    300

    瀏覽量

    38277
  • 通信總線
    +關注

    關注

    0

    文章

    44

    瀏覽量

    9844
  • SDA
    SDA
    +關注

    關注

    0

    文章

    124

    瀏覽量

    28118
收藏 人收藏

    評論

    相關推薦

    詳解IIC總線

    IIC(Inter-Integrated Circuit)集成電路總線,它是種兩線式串行通信總線,又叫I
    發表于 06-07 15:38 ?9694次閱讀
    <b class='flag-5'>一</b><b class='flag-5'>文</b>詳解<b class='flag-5'>IIC</b><b class='flag-5'>總線</b>

    詳解IIC總線

    IIC(Inter-Integrated Circuit)是個多主從的串行總線,又叫I2C,是由飛利浦公司發明的通訊
    發表于 09-12 11:15 ?2100次閱讀
    <b class='flag-5'>一</b><b class='flag-5'>文</b>詳解<b class='flag-5'>IIC</b><b class='flag-5'>總線</b>

    IIC總線串行技術

    IIC總線串行技術的電子書
    發表于 02-19 16:32

    IIC總線協議與SCCB協議的區別

    先簡單介紹IIC總線協議IIC總線是philips公司推出的新
    發表于 08-07 12:43

    常用串行總線協議有哪些

    常用串行總線協議目前常用的微機與外設之間進行數據傳輸的
    發表于 11-03 07:14

    常用串行總線協議有哪些

    常用串行總線協議I2C總線、SPI總線、SCI
    發表于 11-19 06:46

    IIC總線協議的相關資料下載

    (串行數據線)和SCL(串行時鐘線)及上拉電阻組成。通信原理是通過對SCL和SDA線高低電平時序的控制,來 產生I2C總線協議所需要的信號進
    發表于 11-30 08:29

    串行通信中的IIC總線工作原理是什么

    串行通信中的IIC總線工作原理51本身不帶IIC總線 ,使用程序模擬IIC通信
    發表于 12-08 07:52

    IIC協議的相關資料推薦

    STM32 IIC實驗講解,從入門到放棄。文章目錄STM32 IIC實驗講解,從入門到放棄。前言、IICIIC是什么?IIC協議二、代碼部
    發表于 01-17 08:12

    IIC總線協議

    IIC總線協議,感興趣的小伙伴們可以看看。
    發表于 07-26 16:29 ?58次下載

    FPGA基礎知識IIC協議讀寫解析

    很多數字傳感器、數字控制的芯片(DDS、串行ADC、串行DAC)都是通過IIC總線來和控制器通信的。不過IIC
    發表于 05-05 10:17 ?8226次閱讀
    FPGA基礎知識<b class='flag-5'>之</b><b class='flag-5'>IIC</b><b class='flag-5'>協議</b>讀寫解析

    IIC總線協議及應用

    (串行數據線)和SCL(串行時鐘線)及上拉電阻組成。通信原理是通過對SCL和SDA線高低電平時序的控制,來 產生I2C總線協議所需要的信號進
    發表于 11-20 15:21 ?10次下載
    <b class='flag-5'>IIC</b><b class='flag-5'>總線</b><b class='flag-5'>協議</b>及應用

    STC89C52的IIC總線寫EEPROM

    串行通信中的IIC總線工作原理51本身不帶IIC總線 ,使用程序模擬IIC通信
    發表于 11-25 15:51 ?11次下載
    STC89C52的<b class='flag-5'>IIC</b><b class='flag-5'>總線</b>寫EEPROM

    帶你迅速了解常用串行總線IIC協議1

    集成電路總線** (Inter-Intergrated Circuit),通常稱作IICBUS,簡稱為IIC,是種采用多主從結構的串行通信總線
    的頭像 發表于 01-21 17:19 ?1806次閱讀
    <b class='flag-5'>一</b><b class='flag-5'>文</b><b class='flag-5'>帶你</b><b class='flag-5'>迅速</b><b class='flag-5'>了解</b><b class='flag-5'>常用</b><b class='flag-5'>串行</b><b class='flag-5'>總線</b><b class='flag-5'>之</b><b class='flag-5'>IIC</b><b class='flag-5'>協議</b>1

    帶你迅速了解常用串行總線IIC協議3

    集成電路總線** (Inter-Intergrated Circuit),通常稱作IICBUS,簡稱為IIC,是種采用多主從結構的串行通信總線
    的頭像 發表于 01-21 17:20 ?1056次閱讀