提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
目录
前言
IIC 总线使设计人员和厂商都得益
一、IIC的优势
符合 I 2 C 总线的 IC 还有一些功能特别吸引设计人员:
除了这些优点外
二、IIC总线的概念
表 1 I2 C 总线术语的定义
![](https://img-blog.csdnimg.cn/e6f8a89a209f4782a29f1bde08b925b9.png)
三、IIC物理层
IIC物理层的特点
四、IIC协议层
数据的有效性
IIC总线的位传输
起始、停止条件及应答信号
这些信号中,起始信号是必需的,结束信号和应答信号,都可以不要。
下面我们来逐步分析IIC通信的处理流程(附代码)
初始(空闲)状态
因为IIC的 SCL 和SDA 都需要接上拉电阻,保证空闲状态的稳定性
所以IIC总线在空闲状态下SCL 和SDA都保持高电平
代码:
void BE_I_init(void)
{
I2C_CLK_1(); // CLK=1
Delay_Unit5us();
I2C_SDA_1(); // SDA=1
Delay_Unit5us();
}
开始信号
void BE_I_Start(void)
{
I2C_SDA_1(); // SDA=1
I2C_CLK_1(); // CLK=1
Delay_Unit5us(); // start hold 保持时间,必须大于4.7us
I2C_SDA_0(); // SDA=0
Delay_Unit5us(); // start hold 保持时间,必须大于4.7us
I2C_CLK_0(); // CLK=0
Delay_Unit5us(); // start hold 保持时间,必须大于4.7us
}
结束信号
代码:
void BE_I_Stop(void)
{
I2C_SDA_0(); // SDA=0
Delay_Unit5us();
I2C_CLK_1(); // CLK=1
Delay_Unit5us();
I2C_SDA_1(); // SDA=1
Delay_Unit5us();
I2C_CLK_0(); // CLK=0
}
应答信号
![](https://img-blog.csdnimg.cn/0227790f7aa3474aa45a84e98a599411.png)
这表示IIC的应答机制
- 下面的波形:SCL,主机产生的时钟脉冲
- 上面的波形:SDA,主机发送的8位数据
- 中间的波形:SDA,从机在第9个时钟信号进行拉低回应,表示收到了主机发来的数据,拉高则表示不应答
1、ACK
代码:
void BE_I_ACK(void)
{
I2C_CLK_0(); // SCK=0
I2C_SDA_0(); // SDA=0
I2C_CLK_1(); // SCK=1
Delay_Unit5us();
I2C_CLK_0(); // SCK=0
}
2、NACK
代码:
void BE_I_NAK(void)
{
I2C_CLK_0(); // SCK=0
I2C_SDA_1(); // SDA=1
I2C_CLK_1(); // SCK=1
Delay_Unit5us();
I2C_CLK_0(); // SCK=0
}
注:实际上,上面和中间是同样的SDA线,这里只是分开示意。因为IIC应答是一种相互关系,单片机发数据给IIC器件,IIC器件要进行应答,表示收到了数据,同样,单片机接收IIC器件的数据后,也要给IIC器件一个应答。
如果不需要继续读取数据,可发送非应答信号。
五、IIC的数据传输格式
IIC分为7位寻址和10位寻址,因大多数都是7位寻址,这里不过多介绍10位寻址,想了解的小伙伴自己去了解一下
传输数据
字节格式
![](https://img-blog.csdnimg.cn/e41cadbdb8454adbabd2ad385445e236.png)
如上图所示:
- 当产生一个起始信号(S)后,开始数据传输,SAD先输出为高电平,SCL后输出为高电平,紧接着发送了一个从机地址,这个地址共有 7 位。紧接着的第 8 位是数据方向位(R/W)-------’0‘表示发送(写),’1‘表示接受数据(读)。然后主设备释放SDA(在响应的时钟脉冲期间 接收器必须将 SDA 线拉低),SCL电平由低变高,从设备产生ACK信号。每个字节的传输都要跟随有一个应答位,整个过程以接收到停止信号(P)为结束。
- 所有的SDA 信号变化都要在SCL 时钟为低电平时进行,除了开始和结束标志
IIC基本读写过程
数据由主机传输至从机 S : 传输开始信号 (S)
SLAVE_ADDRESS: 从机地址
数据由从机传输至主机 R/W:传输方向选择位,1为读,0为写
IIC的读写操作
上面介绍的是IIC的基本读写过程,下面我们来详细讲述一下IIC写操作的时序逻辑(附代码)
写单个字节
- 开始写操作时,主机先发出起始信号(S),表示开始数据传输。
- 主机发出设备地址(7位)+写操作‘0’(1位)共八位数据,并等待从机应答信号。
- 在收到从机的应答信号之后,继续发送数据(8位),表示需要访问从机的哪一个地址,并等待应答信号。
- 接收到从机的应答信号后,接着发送8位需要写入的数据,随后等待应答信号。
- 写单个字节结束,主机发送停止信号(P)。
uint8 BE_I_WriteB(uint8 data1)
{
uint8 i;
uint8 errFg;
uc_BeWrData = data1;
I2C_CLK_0(); // SCK=0
I2C_SDA_0(); // SDA=0
for (i=0; i<8; i++) // send One byte
{
I2C_CLK_0(); // SCK=0
if (uc_BeWrData & 0x80) //获取最高位
{
I2C_SDA_1(); // DA=1
}
else
{
I2C_SDA_0(); // DA=0
}
uc_BeWrData <<= 1;
Delay_Unit5us();
I2C_CLK_1(); // SCK=1
Delay_Unit5us();
}
if (I2C_SDA_ST) //读取ACK
{
errFg = 1; // 返回是1,为NAK
}
else
{
errFg = 0; // 返回0为ACK
}
I2C_CLK_0(); // SCK=0
return errFg;
}
连续写入多个字节
连续写入多个字节,大致时序同单字节写入一样,可在发送完第一个8位数据,并等待ACK信号后,再次写入一个8位数,并等待ACK信号。直到主机发送停止信号(P)后,停止数据传输。
读单个字节
- 首先由主设备产生起始信号,然后发送从设备地址位和一个写数据位‘0’,等待应答
- 然后发送寄存器地址,才能开始读寄存器(主机要改变通信模式(主机将由发送变为接收)
- 收到应答信号后,主设备再发一个开始信号,然后发送从设备地址位和一个读数据位‘1’
- 然后,从设备产生应答信号并开始发送寄存器中的数据
- 通信以主设备产生的拒绝应答信号(nACK)和结束标志(Stop)结束
- 拒绝应答信号(nACK)产生定义为SDA 数据在第9 个时钟周期一直为高
代码:
uint8 BE_I_ReadB(unsigned char ack)
{
uint8 i; //
I2C_CLK_0(); // sclk=0
I2C_SDA_IN(); //设为输入
_BeRdData =0; //
for (i=0;i<8;i++) //
{
I2CCLK_0(); // sclk=0
Delay_Unit5us();
I2C_CLK_1(); // sclk=1
_BeRdData <<= 1; // Clock high time
if (I2C_SDA_ST) // 接收到1
{
uc_BeRdData |= 0x01; // 数据末位置1 (+1)
} //
} //
I2C_CLK_0(); // sclk=0
if (!ack)
IIC_NAck(); //发送nACK
else
IIC_Ack(); //发送ACK
return uc_BeRdData; //
}
连续读多个字节
通信时序与上面的“读一个字节”类似,上面是读一个字节后就nAck叫停,若要连续写,则发送Ack,直到不需要继续读时再回复nAck。
六、硬件IIC与软件IIC
一:模拟IIC与硬件IIC定义?
模拟I2C一般是用GPIO管脚,用软件控制管脚状态以模拟I2C通信波形。
硬件I2C对应芯片上的I2C外设,有相应I2C驱动电路,其所使用的I2C管脚也是专用。
二:优缺点
1.硬件I2C的效率要远高于软件的,而软件I2C由于不受管脚限制,接口比较灵活。
2.模拟I2C 是通过GPIO,软件模拟寄存器的工作方式,而硬件(固件)I2C是直接调用内部寄存器进行配置。如果要从具体硬件上来看,可以去看下芯片手册。因为固件I2C的端口是固定的,所以会有所区别。
三:如何区分它们
可以看底层配置,比如IO口配置,如果配置了IO口的功能(IIC功能)那就是固件IIC,否则就是模拟
可以看IIC写函数,看里面有木有调用现成的函数或者给某个寄存器赋值,如果有,则肯定是固件IIC功能,没有的话肯定是数据一个bit一个bit模拟发生送的,肯定用到了循环,则为模拟。
根据代码量判断,模拟的代码量肯定比固件的要大。
总结
以上就是IIC的全部内容,本文简单介绍了IIC的使用,希望对大家有帮助!