赞
踩
空闲位:SCL 高电平 SDA低电平
起始位 :SCL 高电平 SDA 高电平到低电平
结束位:SCL 高电平 SDA低电平到高电平
读写状态:数据+响应位
`timescale 1ns/1ns
module IIC_WM(
Clk,
Rst_n,
IIC_SCL, //iic时钟线
IIC_SDA //iic数据总线
);
input Clk;//系统时钟
input Rst_n;//复位
output reg IIC_SCL;//IIC 时钟
inout IIC_SDA;//IIC数据
reg OE;
reg [15:0]cnt;
reg [15:0]IIC_cnt,IIC_cnt_r;
reg [15:0]data_cnt,data_cnt_r;//IIC_cnt 每计数到30,data_cnt加一,IIC_cnt_r计数到30,data_cnt_r加1
wire [7:0]addr;
wire [7:0]data;
reg done;//每当传输完一帧数据30位,done设置为1
reg total_done;//传输完8帧数据置1
reg [3:0]done_cnt;//每次来一个done加1
reg IIC_SDA_tmp;
reg [2:0]ACK;
assign IIC_SDA = OE?IIC_SDA_tmp:1'hz; //oe为1时SDA为输出
parameter CNT_MAX = 124;
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)
cnt <=#1 0;
else if(cnt == CNT_MAX)
cnt <=#1 0;
else if(total_done)
cnt <= #1 0;
else
cnt <=#1 cnt + 1'b1;
//200k IIC_SCL 时钟
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)
IIC_SCL <=#1 0;
else if(cnt == CNT_MAX)
IIC_SCL <=#1 ~IIC_SCL;
else
IIC_SCL <=#1 IIC_SCL;
//200k时钟高低电平各有一个计数器
//IIC_cnt 高电平计数
always@(posedge Clk)
if(!IIC_SCL)case(data_cnt)
//器件地址设置
// 1:IIC_SDA_tmp <=#1 0;end
//器件寄存器地址设置
11:begin IIC_SDA_tmp <=#1 addr[7];OE<=#1 1;endend
//器件数据读取
20:begin IIC_SDA_tmp <=#1 data[7];OE<=#1 1;endendmodule
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。