发布时间:2022-12-02 08:00
IIC通信是一种同步通信方式,同步通信是采用一个同步时钟线,连到收发双方,使收发双方达到完全同步。则IIC通信硬件连接就有四根线VCC、GND、SDA、SCL,SDA是传送数据的,SCL是控制时序的,IIC它是有规矩的,用到这种通信方式,就得按照它的规矩来做,它才会听话,才能完成通信,也称为IIC通信协议。
IIC通信协议:
IIC通信时,需要用到开始信号、停止信号、等待响应信号、发送字节信号、读取字节信号;
开始信号的条件:当SCL为高电平的时候,SDA线上由高到低的跳变被定义为起始条件;
结束信号的条件:当SCL为高电平的时候,SDA线上由低到高的跳变被定义为停止条件;
在设置这些高低电平时,可以在代码中直接设置,这个也叫软件(代码)模拟IIC通信;
IIC通信的起始信号和结束信号:
当 SCL 线为高电平时,SDA 线由高到低的下降沿,为传输开始标志(S)。直到主设备 发出结束信号(P),否则总线状态一直为忙。结束标志(P)规定为,当 SCL 线为高电平 时,SDA 线由低到高的上升沿
IIC通信的应答信号:
IIC 的数据字节定义为 8-bits 长度,对每次传送的总字节数量没有限制。对每一次传输 必须伴有一个应答(ACK)信号,其时钟由主设备提供,而真正的应答信号由从设备发出, 在时钟为高时,通过拉低并保持 SDA 的值来实现。
如果从设备忙,它可以使 SCL 保持在低电平,这会强制使主设备进入等待状态。当从 设备空闲后,并且释放时钟线,原来的数据传输才会继续。
IIC通信的接收数据信号和发送数据信号:
开始标志(S)发出后,主设备会传送一个 7 位的 Slave 地址,并且后面跟着一个第 8 位,称为 Read/Write 位。R/W 位表示主设备是在接受从设备的数据还是在向其写数据。然 后,主设备释放 SDA 线,等待从设备的应答信号(ACK)。每个字节的传输都要跟随有一 个应答位。应答产生时,从设备将 SDA 线拉低并且在 SCL 为高电平时保持低。数据传输总 是以停止标志(P)结束,然后释放通信线路。然而,主设备也可以产生重复的开始信号去 操作另一台从设备,而不发出结束标志。综上可知,所有的 SDA 信号变化都要在 SCL 时钟 为低电平时进行,除了开始和结束标志。
响应信号、发送字节信号,接收字节信号,我都会在代码中实现出来;
此文章并没有实现任何的功能,只是把IIC底层驱动实现出来,你们用到IIC,完全可以把驱动利用起来,下篇文章,我教大家利用IIC实现和OLED屏幕的通信。
废话不多说,直接上图:
IIC点C文件:
#include "iic.h"
//总线引脚定义
sbit SDA = P2^1; /* 数据线 */
sbit SCL = P2^0; /* 时钟线 */
//延迟函数
void IIC_Delay(unsigned char i)//延时一段时间
{
while(i--)
{
_nop_();
_nop_();
}
}
//开始信号
void IIC_Start(void)
{
SDA = 1;
SCL = 1;//当SCL为高电平的时候,SDA线上由高到低的跳变被定义为起始条件
IIC_Delay(5);
SDA = 0;
IIC_Delay(5);
SCL = 0;
}
//停止信号
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;//SCL为高电平的时候,SDA线上由低到高的跳变被定义为停止条件;
IIC_Delay(5);
SDA = 1;
IIC_Delay(5);
}
//等待应答信号(作用很大)
bit IIC_WaitAck(void)
{
bit ackbit;
SCL = 1;
IIC_Delay(5);
ackbit = SDA;
SCL = 0;
IIC_Delay(5);
return ackbit;
}
//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++)
{
SCL = 0;
IIC_Delay(5);
if(byt & 0x80) SDA = 1;
else SDA = 0;
IIC_Delay(5);
SCL = 1;
byt <<= 1;
IIC_Delay(5);
}
SCL = 0;
}
//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
unsigned char i, da;
for(i=0; i<8; i++)
{
SCL = 1;
IIC_Delay(5);
da <<= 1;
if(SDA) da |= 1;
SCL = 0;
IIC_Delay(5);
}
return da;
}
头文件
#ifndef _IIC_H
#define _IIC_H
#include "main.h"
void IIC_Start(void);
bit IIC_WaitAck(void);
void IIC_SendAck(bit ackbit);
void IIC_SendByte(unsigned char byt);
unsigned char IIC_RecByte(void);
#endif