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...