📄 iic_ad75.v
字号:
module IIC_AD75(CLK,EN,SCL,SDA,DATA_OUT,END_IIC,ST,MT,i2c_state);
input CLK,EN;
output SCL;
inout SDA;
output [7:0] DATA_OUT;
output END_IIC,ST,MT;
output [3:0] i2c_state;
reg SCL;
reg SDA_buf;//SDA输入输出数据缓存
reg END_IIC,ST,MT;
reg link; //SDA输出标志
reg phase0,phase1,phase2,phase3;//一个scl时钟周期的四个相位阶段,将一个scl周期分为4段 phase0对应scl的上升沿时刻,phase2对应scl的下降沿时刻,phase1对应scl高电平的中间时刻,phase3对应scl低电平的中间时刻,
reg[7:0] clk_div;//分频计数器
reg[20:0] delay_60ms;//延时计数器
reg h_delay;//延时开始
reg [1:0] main_state;
reg [2:0] state_cnt;
reg [3:0] i2c_state;//对i2c操作的状态 W_tos, W_ths, W_con, W_add, R_tep
reg [5:0] inner_state;//i2c每一操作阶段内部状态
reg[7:0] readData_reg;//读回数据的寄存
reg [15:0] r16_tos;//0110 0100 0000 0000;//100C
reg [15:0] r16_ths;//0000 0000 0000 0000;//0C
reg [7:0] r8_con;//8'b0010 0110;
reg [7:0] r8_mod;//8'b0000 0100;
reg [14:0] d_cnt;
//---------------------------------------------------------------------------------------------------------------------------------------------
parameter stt =6'b000000, //开始
w1 =6'b000001, //第1位
w2 =6'b000010,//第2位
w3 =6'b000011, //第3位
w4 =6'b000100, //第4位
w5 =6'b000101, //第5位
w6 =6'b000110, //第6位
w7 =6'b000111, //第7位
w8 =6'b001000, //第8位
ack =6'b001001, //确认位
R1 =6'b001010,
R2 =6'b001011,
R3 =6'b001100,
R4 =6'b001101,
R5 =6'b001110,
R6 =6'b001111,
R7 =6'b010000,
R8 =6'b010001,
D1 =6'b010010,
D2 =6'b010011,
D3 =6'b010100,
D4 =6'b010101,
D5 =6'b010110,
D6 =6'b010111,
D7 =6'b011000,
D8 =6'b011001,
D9 =6'b011010,
D10 =6'b011011,
D11 =6'b011100,
D12 =6'b011101,
D13 =6'b011110,
D14 =6'b011111,
D15 =6'b100000,
D16 =6'b100001,
RDdata1 =6'b100010,
RDdata2 =6'b100011,
RDdata3 =6'b100100,
RDdata4 =6'b100101,
RDdata5 =6'b100110,
RDdata6 =6'b100111,
RDdata7 =6'b101000,
RDdata8 =6'b101001,
RDdata9 =6'b101010,
RDdata10 =6'b101011,
RDdata11 =6'b101100,
RDdata12 =6'b101101,
RDdata13 =6'b101110,
RDdata14 =6'b101111,
RDdata15 =6'b110000,
RDdata16 =6'b110001,
ack_1 =6'b110010,
ack_2 =6'b110011,
ack_3 =6'b110100,
ack_4 =6'b110101,
stop =6'b110110; //结束位
parameter div_parameter = 100;// 分频系数,ADT75最大支持400K时钟速率
//---------------------------------------------------------------------------------------------------------------------------------------------
assign SDA=link ? SDA_buf:1'bz;
assign DATA_OUT = readData_reg ;
//------------------------------------------------------SCL-----------------------------------------------------------------------------------
always@(posedge CLK or negedge EN)
begin
if(!EN)
begin
clk_div<=0;
phase0<=0;
phase1<=0;
phase2<=0;
phase3<=0;
end
else
begin
if(clk_div!=div_parameter-1)
clk_div<=clk_div+1;
else
clk_div<=0;
if(phase0)
phase0<=0;
else
if(clk_div==99)
phase0<=1;
if(phase1)
phase1<=0;
else
if(clk_div==24)
phase1<=1;
if(phase2)
phase2<=0;
else
if(clk_div==49)
phase2<=1;
if(phase3)
phase3<=0;
else
if(clk_div==74)
phase3<=1;
end
end
//-----------------------------------ADT75操作部分-----------------------------------------------
always@(posedge CLK)
begin
if(!EN)
begin
main_state<=2'b00;
i2c_state<=4'b0000;
inner_state<=stt;
link<=0;
readData_reg<=0;
SCL <= 1'bz;
SDA_buf<=1;
state_cnt<=3'b000;
r16_tos<=16'b0110010000000000;//100C
r16_ths<=16'b0000000000000000;//0C
r8_con<=8'b00100110;
r8_mod<=8'b00000100;
ST<=0;
MT<=0;
end
else
begin
case(main_state)
2'b00: //等待读写要求
begin
SDA_buf<=1;
link<=0;
inner_state<=stt;
i2c_state<=4'b0000;
SCL <= 0;
if(EN)
begin
main_state<=2'b10;
end
else
main_state<=2'b00;
end
2'b10:
begin //WRITE ADT75
if(phase0)
SCL<=1;
else
if(phase2)
SCL<=0;
case(i2c_state)
//iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
// W_add state1
4'b0000: //ini_add
begin
case(inner_state)
stt: begin
if(phase1)
begin
link<=1;
SDA_buf<=0;
end
if(phase3&link)
begin
inner_state<=w1;
SDA_buf<=1; //------------------------------1
link<=1;
end
end
w1:
if(phase3)
begin
SDA_buf<=0; //------------------------------0
link<=1;
inner_state<=w2;
end
w2:
if(phase3)
begin
SDA_buf<=0; //------------------------------0
link<=1;
inner_state<=w3;
end
w3:
if(phase3)
begin
SDA_buf<=1; //------------------------------1
link<=1;
inner_state<=w4;
end
w4:
if(phase3)
begin
SDA_buf<=0; //-----------------------------A2
link<=1;
inner_state<=w5;
end
w5:
if(phase3)
begin
SDA_buf<=0; //------------------------------A1
link<=1;
inner_state<=w6;
end
w6:
if(phase3)
begin
SDA_buf<=0; //------------------------------A0
link<=1;
inner_state<=w7;
end
w7:
if(phase3)
begin
SDA_buf<=0; //------------------------------R/W
link<=1;
inner_state<=w8;
end
w8:
if(phase3)
begin
link<=0; //SDA TURN
inner_state<=ack;
end
ack:
begin
if(phase0)
SDA_buf<=SDA;
if(phase1)
begin
if(SDA_buf==1)
begin
main_state<=2'b00;
end
end
if(phase3)
begin
link<=1;
SDA_buf<=0;//---------------------------------------------------------------------0 for the 4 register adder's NUM0 all 0 add[7]
inner_state<=R1;
i2c_state<=4'b0001;//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
end
end
endcase
end
//==========================================================
4'b0001: //w_add
begin
case(inner_state)
R1:
if(phase3)
begin
link<=1;
SDA_buf<=0; //------------------------------add6
inner_state<=R2;
end
R2:
if(phase3)
begin
SDA_buf<=0; //------------------------------add5
link<=1;
inner_state<=R3;
end
R3:
if(phase3)
begin
SDA_buf<=0; //------------------------------add4
link<=1;
inner_state<=R4;
end
R4:
if(phase3)
begin
SDA_buf<=0; //-----------------------------add3
link<=1;
inner_state<=R5;
end
R5:
if(phase3)
begin
SDA_buf<=0; //------------------------------add2
link<=1;
inner_state<=R6;
end
R6:
if(phase3)
begin
SDA_buf<=0; //------------------------------add1
link<=1;
inner_state<=R7;
end
R7:
if(phase3)
begin
SDA_buf<=0; //------------------------------add0
link<=1;
inner_state<=R8;
end
R8:
if(phase3)
begin
link<=0; //SDA TURN
inner_state<=ack_2;
end
ack_2:
begin
if(phase0)
SDA_buf<=SDA;
if(phase1)
begin
if(SDA_buf==1)
begin
main_state<=2'b00; //********************************
end
end
if(phase3)
begin
link<=1;
SDA_buf<=0; //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@2
inner_state<=ack_4;
end
end
ack_4: begin
if(phase1)
begin
link<=1;
SDA_buf<=1;
end
if(phase3)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -