狀態機實現對I2C器件的寫操作

2021-06-20 15:38:50 字數 4299 閱讀 7163

0,直接在ise裡面編譯過邏輯不正常,在synplify,不勾選fsm_exporler可以得到正確結果,否則也是錯誤結果。

1,狀態機實現。

2,不檢測ack,但滿足ack的時序。

3,使用24c02測試通過。

4,繼續補充。

5,怎麼能在這裡面輸入**格式?

module wr_a_byte_to_24c02(

input clk,rst,

input [6:0] dev_addr,

input [7:0] dat,

input [7:0] byte_addr,

input do_wr,

output reg fsm_done  ,

output  scl,sda

);wire done ;

parameter idle = 0;

parameter dev_chk = 1;

parameter dev_chk_ack =2 ;

parameter send_byte_addr =3 ;

parameter send_byte_addr_ack=4 ;

parameter send_dat =5 ;

parameter send_dat_ack =6 ;

parameter done =7 ;

parameter dev_chk_ack_done=8;

reg [31:0] st ;

reg [7:0] dat_to_i2c;

reg sta,wr,sto;

always @ (posedge clk)

if (rst) begin

st <=idle;

endelse

begin

if (done)<=0;

case (st)

idle :begin if (do_wr) st<=dev_chk ;end

dev_chk : begin st<= dev_chk_ack;  dat_to_i2c[7:0]<= ;  sta<=1;wr<=1;sto<=0;end

dev_chk_ack: if (done )  st<=dev_chk_ack_done ;

dev_chk_ack_done: st <= send_byte_addr ;

send_byte_addr : begin st <=send_byte_addr_ack ;  sta<=0;wr<=1;sto<=0; dat_to_i2c[7:0]<=byte_addr ; end

send_byte_addr_ack : if (done)  st <= send_dat;

send_dat : begin st <= send_dat_ack ;  sta<=0;wr<=1;sto<=1;dat_to_i2c[7:0] <= dat; end

send_dat_ack: if  (done)  st <=  done ;

done :begin  st<=idle; end

default  st<= idle;

endcase

endeeprom_fsm u1(

.clk(clk),

// .sta(1'b1),

//.sto(1'b1),

//.wr(1'b1),

.sta(sta),

.sto(sto),

.wr(wr),

.dat(dat_to_i2c),

.done(done ),

.scl(scl),

.sda(sda)

);always @ (posedge clk)fsm_done<=st == done ;

endmodule

module eeprom_fsm(

input clk,rst,

input sta,sto,wr,

input [7:0]dat,

output reg done,

output    scl,sda

);reg sclr,sdar;

assign scl = (sclr)?1'bz:0 ;

assign sda = (sdar)?1'bz:0 ;

reg [31:0] st ;

parameter div_cntr = 1000;

reg [31:0] c ;

always @ (posedge clk)

if ((c==div_cntr)||(st==10)) c<=0;

else c <= c+1 ;

wire i2c_clk = (c==div_cntr)  ;

reg [7:0] idx =0;

reg outbit ;

always @ (posedge clk)

case (idx[2:0])

0:outbit <= dat[7 ] ;

1:outbit <= dat[6 ] ;

2:outbit <= dat[5 ] ;

3:outbit <= dat[4 ] ;

4:outbit <= dat[3 ] ;

5:outbit <= dat[2 ] ;

6:outbit <= dat[1 ] ;

7:outbit <= dat[0 ] ;

endcase

wire go = sta|sto|wr;

reg [4:0]cc;always @ (posedge clk)cc<=cc+1;

always @ (posedge clk)

if (rst)

begin

st <=0 ;

sdar<=1;

sclr<=1;

end else

case(st )

0:begin sclr<=1;sdar<=1;if (i2c_clk) st<=10 ;end

10: begin idx<=0;if (go) st <= 1;end

1:  if (sta) st<=2 ; else st <= 100;

2: begin  sclr<=1 ;sdar <= 1 ; if (i2c_clk) st<=3 ;end

3: begin  sclr<=1 ;sdar <= 0 ; if (i2c_clk) st<=4 ;end

4: begin  sclr<=0 ;sdar <= 0 ; if (i2c_clk) st<=5 ;end

5: begin  st <= 100 ;end

100:st<=101;

101:st<=102;

102:begin sclr<=0;sdar<=outbit ; if (i2c_clk) st<=103;end

103:begin sclr<=1;sdar<=outbit ; if (i2c_clk) st<=104;end

104:begin sclr<=1;sdar<=outbit ; if (i2c_clk) st<=105;end

105:begin sclr<=0;sdar<=outbit ; if (i2c_clk) st<=106;end

106: if(idx==7)st<=110;else begin idx<=idx+1; st<=100;end

110:begin sclr<=0;sdar<=1 ; if (i2c_clk) st<=111;end

111:begin sclr<=1;sdar<=1 ; if (i2c_clk) st<=112;end

112:begin sclr<=1;sdar<=1 ; if (i2c_clk) st<=115;end

115:begin sclr<=0;sdar<=1 ; if (i2c_clk) st<=116;end

116:begin sclr<=0;sdar<=1 ; if (i2c_clk) st<=200;end

200: if(sto) st<=201 ; else st<=300;

201: begin sclr<=1;sdar<=0 ; if (i2c_clk) st<=202;end

202: begin sclr<=1;sdar<=1 ; if (i2c_clk) st<=203;end

203: begin sclr<=1;sdar<=1 ; if (i2c_clk) st<=300;end

300: st<=301;

301: st<=10;

default st<=0;

endcase

always @ (posedge clk)

if (st==300)done<=1;else  done<=0;

endmodule

波形測試正確

I2C器件的從裝置位址設定

i2c中24c02從位址設定 今天看了一下at24c02的程式,發現 從裝置位址 有點不明白,現在以at24c02為例子說說我的見解。首先,先看一下at24c02的晶元資料,我們會發現at24c02有三個位址a0,a1,a2。同時,我們會在資料的device address介紹發現i2c器件一共有七...

對i2c子系統的理解

驅動i2c控制器歸根到底是對iic控制器的暫存器進行讀寫,因此,理解了linux中是怎樣通過層層呼叫來操作iic的暫存器,便理解了整個iic子系統的輪廓。下面以公司使用的重力感測器 bma250 驅動為例來描述這個輪廓。首先介紹三個比較重要的驅動檔案 bma250.c drivers gsensor...

linux的I2C驅動 讀寫操作

接下來開始整體的介紹i2c,主要參考 linux裝置驅動開發詳解 1 i2c核心 i2c核心提供了i2c匯流排驅動和裝置驅動的註冊 登出方法,i2c通訊方法。2 i2c匯流排驅動 i2c匯流排驅動是對i2c硬體體系結構中介面卡的實現。i2c匯流排驅動主要包含i2c介面卡資料結構i2c adapter...