1.I2C的简介
I2C是一种半双工同步通信方式,半双工意味着可以分时收发,同步意味着有公共的时钟线去控制通信的速度。需要两根信号线,SDA和SCL。I2C支持一主多从,SDA和SCL各需要一个上拉电阻。SCL和SDA要配置成开漏输出模式。 I2C可以驱动四针的OLED显示屏,与MPU6050进行通信,读写EPPROM等。
I2C的时序一共有六块拼图,分别是:起始条件、终止条件、发送一个字节、接收一个字节、发送应答和接收应答。模拟I2C时序需要严格地改变两根信号线的电平来完成这六块拼图,硬件I2C也是需要由这六块拼图搭建而成。
2.I2C的时序
3.I2C的数据帧
I2C有三种基本类型的数据帧,除去起始条件和终止条件外,本质上就是发送一个字节随机接收应答,接收一个字节随即发送应答。
4.I2C的实现
软件模拟I2C时,除了需要严格复制它的标准时序,还应注意高电平的保持时间(软件延时),为了让这6块拼图能拼上对齐,还应在每块拼图结束时必要地改变时钟线以及释放数据线。
#define SDA0() P24 = 0
#define SDA1() P24 = 1
#define SCL0() P25 = 0
#define SCL1() P25 = 1
#define SDA P24
#define SCL P25
void i2c_sim_start(void)
{
SDA1();
delay_5us();
SCL1();
delay_5us();
SDA0();
delay_5us();
SCL0(); //跟发送字节的拼图对齐
delay_5us();
}
void i2c_sim_sendbyte(unsigned char dat)
{
unsigned char i;
for(i = 0;i < 8;i++)
{
SDA = dat & (0x80 >> i); //依次从高位发送
SCL1();
delay_5us();
SCL0();
delay_5us();
}
}
bit i2c_sim_receiveack(void)
{
bit ack = 0;
SDA1();
delay_5us();
SCL1();
delay_5us();
ack = SDA;
SCL0();
return ack;
}
unsigned char i2c_sim_receivebyte(void)
{
unsigned char i;
unsigned char byte = 0x00;
SDA1(); //释放总线
delay_5us();
for(i = 0;i< 8;i++)
{
SCL1();
delay_5us();
if(SDA)
{
byte |= (0x80 >> i);
}
SCL0();
delay_5us();
}
return byte;
}
void i2c_sim_sendack(bit ack)
{
SDA = ack;
SCL1();
delay_5us();
SCL0();
delay_5us();
}
void i2c_sim_stop(void)
{
SDA0();
delay_5us();
SCL1();
delay_5us();
SDA1();
delay_5us();
}