📄 iicreciver.v
字号:
// VERSION: ver1.0
// MODULE: iicreciver
// Author: HuangRui
// ============================================================
// File Name: iicreciver.v
// Module Name(s):
// iicreciver
// ============================================================
// ************************************************************
// DO NOT EDIT THIS FILE!
//
// 08/14/2007 Full Version
// ************************************************************
//Copyright (C) 2004-2007 Beijing BOHUI Technology Corporation
//***************************************************************
//module based iic specification.
//NOTE:
// FPGA WRITE ADDRESS:adr_iic_wr=8'he2
// FPGA READ ADDRESS:adr_iic_rd=8'he3
// Modify these two parameters according your design!
//iic write data format:
// start+device_address(7bit)+wr(=1,1bit)+ack(1bit)+outad(8bit)+ack(1bit)+outdata(8bit)+ack(1bit)+stop;
// ack(1bit) is slave to master!
//iic read data format:
// start+dev_adr(7bit)+rd(=0,1bit)+ack(1bit)+indata(8bit)+A(1bit)+stop;
// ack is slave to master!
//****************************************************************
module iicreciver ( clk27M,
sda,scl,
outad,outdata,
indata,
outclk
);
input clk27M; //system clock
input scl;
inout sda; //bidirection
output [7:0] outad;
output [7:0] outdata;
output outclk;
input [7:0] indata;
reg outclk;
reg [7:0] outad,outdata;
reg start;
reg [1:0] sda_buf;
reg [9:0] scl_buf;
reg stop;
reg [15:0] count;
reg [7:0] slave_adr,byteout;
reg sda_rdout,oe;
parameter adr_iic_wr=8'he2, //iic write address
adr_iic_rd=8'he3; //iic read address
always@(posedge clk27M)
begin
scl_buf<={scl_buf[8:0],scl};
sda_buf<={sda_buf[0],sda};
end
always@(posedge clk27M)
begin
if((&{sda_buf[1],!sda_buf[0]})&&(scl_buf[0]==1)) //start condition
begin
start<=1;
end
else if(&{scl_buf[9:1],!scl_buf[0]})
begin
start<=0;
end
end
always@(posedge clk27M)
begin
if((&{!sda_buf[1],sda_buf[0]})&&(scl_buf[0]==1)) //stop condition
begin
stop<=1;
end
else if((&{sda_buf[1],!sda_buf[0]})&&(scl_buf[0]==1))
begin
stop<=0;
end
end
always@(count,slave_adr)
begin
if((count==18)&&(slave_adr==adr_iic_rd)) //master read iic end
begin
outclk=stop;
end
else if((count==28)&&(slave_adr==adr_iic_wr)) //master write iic end
begin
outclk=stop;
end
else
begin
outclk=0;
end
end
always@(posedge clk27M)
begin
if(start==1)
begin
count<=16'b0;
end
else
begin
if(&{~(scl_buf[9:1]),scl_buf[0]}) //count at posedge scl
begin
count<=count+16'b1;
end
end
end
wire sda = oe ? sda_rdout : 1'bZ;
always@(posedge clk27M)
begin
if(&{~(scl_buf[9:6]),scl_buf[5:0]})//上升沿后5个时钟clk27M
begin
if(count<9)
begin
slave_adr[0]<=sda_buf[0];
slave_adr[7:1]<=slave_adr[6:0];
end
else if((count>9)&&(count<18))
begin
if(slave_adr==adr_iic_wr)
begin
outad[0]<=sda_buf[0];
outad[7:1]<=outad[6:0];
end
end
else if((count>18)&&(count<27))
begin
if(slave_adr==adr_iic_wr)
begin
outdata[0]<=sda_buf[0];
outdata[7:1]<=outdata[6:0];
end
end
end
else if(&{scl_buf[9:1],!scl_buf[0]})//negedge scl
begin
if(count==8)
begin
sda_rdout<=0;
end
else if((count>8)&&(count<17))
begin
if(slave_adr==adr_iic_rd)
begin
sda_rdout<=byteout[7];
byteout[7:1]<=byteout[6:0];
byteout[0]<=0;
end
end
else if((count==17)||(count==26))
begin
if(slave_adr==adr_iic_wr)
begin
sda_rdout<=0;
end
end
end
else if(&{scl_buf[9:7],~(scl_buf[6:0])}) //6 clk27M clock after negedge scl
begin
if(count==8)
begin
oe<=1;
if(slave_adr==adr_iic_rd)
begin
byteout<=indata;
end
end
else if((count>8)&&(count<17))
begin
if(slave_adr==adr_iic_rd)
begin
oe<=1;
end
else
begin
oe<=0;
end
end
else if((count==17)||(count==26))
begin
if(slave_adr==adr_iic_wr)
begin
oe<=1;
end
else
begin
oe<=0;
end
end
else
begin
oe<=0;
end
end
end
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -