1.简介
1. I2C 属于同步通信。 SCL 时钟线负责收发双方的时钟节拍, SDA 数据线负责传输数据。
I2C 的发送方和接收方都以 SCL 这个时钟节拍为基准进行数据的发送和接收。
2.一般应用于板内通信。
2.和uart的异同
a.数据格式
UART: 每个字节中,都有一个起始位、 8 个数据位、 1 位停止位。
I2C: 分为起始信号、数据传输部分、停止信号。
其中数据传输部分,可以一次通信过程传输很多个字节,字节数是不受限制的。而每个字节的数据最后也跟了一位,这一位叫做应答位,通常用 ACK 表示,有点类似于 UART的停止位。
b.起始信号
UART: 起始信号是从一直持续的高电平出现一个低电平标志起始位;
I2C: SCL 为高电平期间, SDA 由高电平向低电平变化产生一个下降沿,表示起始信号。
c.数据位
UART: 是低位在前,高位在后; 通信数据位是固定长度,波特率分之一,一位一位固定时间发送;
I2C:通信是高位在前,低位在后。没有固定波特率,一位一位固定时间发送。
3.传输协议
每一位信号的时序流程。
起始:SCL在高电平的时候,SDA下降沿;
结束:SCL在低电平的时候,SDA上升;
当SCL在低电平的时候,数据位允许变动。当SCL在高电平的时候,数据位不允许变动。
字节级的传输
起始位,从机地址,数据方向。
起始
void I2CStart()
{
I2C_SDA = 1; // 首先确保 SDA 、 SCL 都是高电平
I2C_SCL = 1;
I2CDelay();
I2C_SDA = 0; // 先拉低 SDA
I2CDelay();
I2C_SCL = 0; // 再拉低 SCL
}
结束
void I2CStop()
{
I2C_SCL = 0; // 首先确保 SDA 、 SCL 都是低电平
I2C_SDA = 0;
I2CDelay();
I2C_SCL = 1; // 先拉高 SCL
I2CDelay();
I2C_SDA = 1; // 再拉高 SDA
I2CDelay();
}
往总线写入一字节
bit I2CWrite(unsigned char dat)//返回值为从机应答值
{
bit ack; // 用于暂存应答位的值
unsigned char mask; // 用于探测字节内某一位值的掩码变量
for (mask=0x80; mask!=0; mask>>=1) // 从高位到低位依次进行
{
if ((mask&dat) == 0) // 该位的值输出到 SDA 上
I2C_SDA = 0;
else
I2C_SDA = 1;
I2CDelay();
I2C_SCL = 1; 拉高 SCL
I2CDelay();
I2C_SCL = 0; // 再拉低 SCL ,完成一个位周期
}
I2C_SDA = 1; //8 位数据发送完后,主机释放 SDA ,以检测从机应答
I2CDelay();
I2C_SCL = 1; // 拉高 SCL
ack = I2C_SDA; // 读取此时的 SDA 值,即为从机的应答值
I2CDelay();
I2C_SCL = 0; // 再拉低 SCL 完成应答位,并保持住总线
return ack; // 返回从机应答值
}