lattice LFE3-17EA 调试记录

通过IIC控制EP936E


IIC读写代码


//
//                                                I2c Byte Write Mode
//          _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   
// SCL:  __| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_
//       ___   ___ ___ ___ ___ ___ ___ ___         ___ ___ ___ ___ ___ ___ ___ ___     ___ ___ ___ ___ ___ ___ ___ ___       ______________
// SDA:     |_|___|___|___|___|___|___|___|_______|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|_____|
//              0   1   1   1  S3  S2  S1  W=0 ACK A7  A6  A5  A4  A3  A2  A1  A0  ACK D7  D6  D5  D4  D3  D2  D1  D0  ACK STOP
//      [START]                                                                                                           [STOP]
//            |<---SLAVE    ADDRESS---------->|   |<-----REGISTER ADDRESS--------->|  |<------------DATA------------->|
//




//                                               I2c Byte Read Mode
//          _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _
// SCL:  __| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_| |_
//       ___   ___ ___ ___ ___ ___ ___ ___         ___ ___ ___ ___ ___ ___ ___ ___     _   ___ ___ ___ ___ ___ ___ ___ ___     ___ ___ ___ ___ ___ ___ ___ ___ ___   ______
// SDA:     |_|___|___|___|___|___|___|___|_______|___|___|___|___|___|___|___|___|___| |_|___|___|___|___|___|___|___|   |___|___|___|___|___|___|___|___|___|   |_|
//              0   1   1   1  S3  S2  S1  W=0 ACK A7  A6  A5  A4  A3  A2  A1  A0  ACK     0   1   1   1  S3  S2  S1   R=1 ACK D7  D6  D5  D4  D3  D2  D1  D0  ACK 
//       [START]                                                                     [START]                                                                      [STOP]     
//            |<---SLAVE    ADDRESS------- --->|   |<-----REGISTER ADDRESS--------->|      |<-------SLAVE    ADDRESS------>|   |<------------DATA------------->|
//
//
//
// 
//
// CLK: 50MHz   








module iic_com
(
    input CLK,
input RSTn,
 
input [1:0] Start_Sig,             //read or write command
input [7:0] Addr_Sig,              //eeprom words address
input [7:0] Addr_offset,           //Offset Address   
input [7:0] WrData,                //eeprom write data
output [7:0] RdData,               //eeprom read data
output Done_Sig,                   //eeprom read/write finish
 
output SCL,
inout SDA
 
);


parameter FPXS = 12'd500;                //100Khz的时钟分频系数
parameter C1_1= FPXS[11:2];               //C1_1=FPXS/4
parameter C1_2= FPXS[11:1];              // C1_2=FPXS/2
parameter C1_3= FPXS[11:2]+FPXS[11:1];              //C1_3=(FPXS/4)*3
parameter C1_4= FPXS;
parameter C1_5= FPXS+FPXS[11:2];           //C1_3=(FPXS/4)*5                          
 
reg [4:0]i;
reg [4:0]Go;
reg [11:0]C1;
reg [7:0]rData;
reg rSCL;
reg rSDA;
reg isAck;
reg isDone;
reg isOut;
 
assign Done_Sig = isDone;
assign RdData = rData;
assign SCL = rSCL;
assign SDA = isOut ? rSDA : 1'bz;        //SDA数据输出选择


//****************************************// 
//*             I2C读写处理程序            *// 
//****************************************// 
always @ ( posedge CLK or negedge RSTn )
if( !RSTn )  begin
i <= 5'd0;
Go <= 5'd0;
C1 <= 10'd0;
rData <= 8'd0;
rSCL <= 1'b1;
rSDA <= 1'b1;
isAck <= 1'b1;
isDone <= 1'b0;
isOut <= 1'b1;
end
else if( Start_Sig[0] )                     //I2C 数据写
    case( i )
   
   0: //发送IIC开始信号
begin
isOut <= 1;                         //SDA端口输出

if( C1 == 0 ) rSCL <= 1'b1;
else if( C1==C1_4 ) rSCL <= 1'b0;       //SCL由高变低
 
if( C1 == 0 ) rSDA <= 1'b1; 
else if( C1==C1_2 ) rSDA <= 1'b0;        //SDA先由高变低 
 
if( C1==C1_5 -1) begin C1 <= 10'd0; i <= i + 1'b1; end
else C1 <= C1 + 1'b1;
end
 
1: // Write Device Addr       写设备地址
begin rData <= {8'h76}; i <= 5'd8; Go <= i + 1'b1; end         
 
2: // Wirte Word Addr 写寄存器地址
begin rData <= Addr_Sig; i <= 5'd8; Go <= i + 1'b1; end
 
3: // Wirte Offset Address 写页地址
begin rData <= Addr_offset; i <= 5'd8; Go <= i + 1'b1; end  

4: // Write Data 写数据
begin rData <= WrData; i <= 5'd8; Go <= i + 1'b1; end
 
5: //发送IIC停止信号
begin
   isOut <= 1'b1;
 
   if( C1 == 0 ) rSCL <= 1'b0;
   else if( C1==C1_1 ) rSCL <= 1'b1;     //SCL先由低变高       

if( C1 == 0 ) rSDA <= 1'b0;
else if( C1==C1_3 ) rSDA <= 1'b1;     //SDA由低变高  
 
if( C1==C1_5 -1 ) begin C1 <= 10'd0; i <= i + 1'b1; end
else C1 <= C1 + 1'b1; 
end
 
6:
begin isDone <= 1'b1; i <= i + 1'b1; end       //写I2C 结束
 
7: 
begin isDone <= 1'b0; i <= 5'd0; end
 
8,9,10,11,12,13,14,15:                         //发送Device Addr/Word Addr/Write Data
begin
    isOut <= 1'b1;
 rSDA <= rData[15-i];                      //高位先发送
 
 if( C1 == 0 ) rSCL <= 1'b0;
    else if( C1==C1_1 ) rSCL <= 1'b1;         //SCL高电平100个时钟周期,低电平100个时钟周期
 else if( C1==C1_3 ) rSCL <= 1'b0; 
 
 if( C1==C1_4 -1 ) begin C1 <= 10'd0; i <= i + 1'b1; end     //产生250Khz的IIC时钟
 else C1 <= C1 + 1'b1;
end
 
16:                                          // waiting for acknowledge
begin
    isOut <= 1'b0;                            //SDA端口改为输入
    if( C1==C1_2 ) isAck <= SDA;             //读取IIC 从设备的应答信号
 
 if( C1 == 0 ) rSCL <= 1'b0;
 else if( C1==C1_1 ) rSCL <= 1'b1;         //SCL高电平100个时钟周期,低电平100个时钟周期
 else if( C1==C1_3 ) rSCL <= 1'b0;
 
 if( C1==C1_4 -1 ) begin  C1 <= 10'd0; i <= i + 1'b1; end    //产生250Khz的IIC时钟
 else C1 <= C1 + 1'b1; 
end
 
16:
if( isAck != 0 ) i <= 5'd0;
else i <= 5'd0; 
// else i <= Go; 

     endcase

 else if( Start_Sig[1] )                     //I2C 数据读
   case( i )

0: // Start
begin
     isOut <= 1;                      //SDA端口输出
     
     if( C1 == 0 ) rSCL <= 1'b1;
  else if( C1==C1_4 ) rSCL <= 1'b0;      //SCL由高变低
 
if( C1 == 0 ) rSDA <= 1'b1; 
else if( C1==C1_2 ) rSDA <= 1'b0;     //SDA先由高变低 
 
if( C1==C1_5 -1 ) begin C1 <= 10'd0; i <= i + 1'b1; end
else C1 <= C1 + 1'b1;
end
 
1: // Write Device Addr(设备地址)
begin rData <= 8'h76; i <= 5'd10; Go <= i + 1'b1; end
 
2: // Wirte Word Addr(EEPROM的写地址)
begin rData <= Addr_Sig; i <= 5'd10; Go <= i + 1'b1; end
 
3: // Wirte Offset Address 写页地址
begin rData <= Addr_offset; i <= 5'd10; Go <= i + 1'b1; end  

4: // Start again
begin
    isOut <= 1'b1;
     
    if( C1 == 0 ) rSCL <= 1'b0;
 else if( C1==C1_1 ) rSCL <= 1'b1; 
 else if( C1==C1_5 ) rSCL <= 1'b0;
 
    if( C1 == 0 ) rSDA <= 1'b0; 
 else if( C1==C1_1 ) rSDA <= 1'b1;
 else if( C1==C1_3 ) rSDA <= 1'b0;  
 
 if( C1 == 300 -1 ) begin C1 <= 10'd0; i <= i + 1'b1; end
 else C1 <= C1 + 1'b1;
end
 
5: // Write Device Addr ( Read )
begin rData <= 8'h77; i <= 5'd10; Go <= i + 1'b1; end

6: // Read Data
begin rData <= 8'd0; i <= 5'd20; Go <= i + 1'b1; end
 
7: // Stop
begin
    isOut <= 1'b1;
    if( C1 == 0 ) rSCL <= 1'b0;
 else if( C1==C1_1 ) rSCL <= 1'b1; 

 if( C1 == 0 ) rSDA <= 1'b0;
 else if( C1==C1_3 ) rSDA <= 1'b1;
 
 if( C1==C1_5 -1 ) begin C1 <= 10'd0; i <= i + 1'b1; end
 else C1 <= C1 + 1'b1; 
end
 
8:                                                       //写I2C 结束
begin isDone <= 1'b1; i <= i + 1'b1; end
 
9: 
begin isDone <= 1'b0; i <= 5'd0; end
 

10,11,12,13,14,15,16,17:                                  //发送Device Addr(write)/Word Addr/Device Addr(read)
begin
     isOut <= 1'b1;      
  rSDA <= rData[16-i];                                //高位先发送
 
  if( C1 == 0 ) rSCL <= 1'b0;
else if( C1==C1_1 ) rSCL <= 1'b1;                   //SCL高电平100个时钟周期,低电平100个时钟周期
else if( C1==C1_3 ) rSCL <= 1'b0; 
 
if( C1==C1_4 -1 ) begin C1 <= 10'd0; i <= i + 1'b1; end   //产生250Khz的IIC时钟
else C1 <= C1 + 1'b1;
end
      
18: // waiting for acknowledge
begin
     isOut <= 1'b0;                                       //SDA端口改为输入
    
  if( C1==C1_2 ) isAck <= SDA;                        //读取IIC 的应答信号
 
if( C1 == 0 ) rSCL <= 1'b0;
else if( C1==C1_1 ) rSCL <= 1'b1;                 //SCL高电平100个时钟周期,低电平100个时钟周期
else if( C1==C1_3 ) rSCL <= 1'b0;
 
if( C1==C1_4 -1 ) begin C1 <= 10'd0; i <= i + 1'b1; end     //产生250Khz的IIC时钟
else C1 <= C1 + 1'b1; 
end
 
19:
     if( isAck != 0 ) i <= 5'd0;           // if( isAck != 0 ) i <= 5'd0;
else i <= Go;
 
 
20,21,22,23,24,25,26,27: // Read data
begin
    isOut <= 1'b0;
    if( C1==C1_2 ) rData[26-i] <= SDA;                              //高位先接收
 
 if( C1 == 0 ) rSCL <= 1'b0;
 else if( C1==C1_1 ) rSCL <= 1'b1;                  //SCL高电平100个时钟周期,低电平100个时钟周期
 else if( C1==C1_3 ) rSCL <= 1'b0; 
 
 if( C1==C1_4 -1 ) begin C1 <= 10'd0; i <= i + 1'b1; end     //产生250Khz的IIC时钟
 else C1 <= C1 + 1'b1;
end  
 
28: // no acknowledge
begin
    isOut <= 1'b1;
 
 if( C1 == 0 ) rSCL <= 1'b0;
 else if( C1==C1_1 ) rSCL <= 1'b1;
 else if( C1==C1_3 ) rSCL <= 1'b0;
 
 if( C1==C1_4 -1 ) begin C1 <= 10'd0; i <= Go; end
 else C1 <= C1 + 1'b1; 
end

endcase





endmodule

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值