本章我们将向大家介绍如何利用STM32的普通IO口模拟IIC时序,并实现和24C02之间的双向通信,实现24C02的读写,并将结果通过串口printf输出,学习目标是掌握IIC协议,学会操作AT24C02。
1.1 I2C 简介
I2C 总线时 PHILIPS 公司推出的一种串行总线,具备多主机系统所需的包括总线仲裁和高低速器件同步功能的高性能串行总线。 它只需要两跟双向的信号线, 一根数据线 SDA,一个是时钟线 SCL。在 I2C 总线上面,每个器件都有自己相应的 I2C 地址,所以在两个器件之间进行通信的时候, 都要首先呼叫你想要通信的器件地址, 然后等待相应的从器件进行应答之后才开始通信。首先我们来看一下,一个 I2C 信号传输的一个过程,如图:
从图上我们可以看出在I2C上面一个完整信号的传输过程,一定要有一个始信号,还有一个结束信号,在每个字节传输结束的时候,从机还要提供一个应答信号,一个完整的信号传输就是这样子。接下来我们来看一下,I2C总线上面对起始信号、应答信号、结束信号、还有高低电平的协定是怎么样的呢?这里有两个要注意的要点:
1、在总线空闲的时候,SDA和SCL都是高电平。
2、在SCL为高电平期间,SDA必须保持稳定。所以SDA改变状态最好在SCL为低电平时,如果在高电平改变的话会被认为是一种有效信号(如:起始信号或者结束信号)。
1.起始信号
起始信号简介SCL线为高电平期间,SDA线由高电平向低电平变化表示起始信号,信号时序如图:
这里要注意的是,在I2C总线上面,当总线空闲的时候,SCL和SDA都是高电平的。起始信号,它是需要有一定的保持时间的,在SDA从高电平向低电平跳变的时候,两个先必须至少保持4.7us的时间,而跳变之后,也要保持SCL高电平和SDA低电平要至少4us的时间(从这里我们看出I2C总线速率已经决定了)。
IO口模拟起始信号
//产生起始信号
void I2C_Start(void)
{
I2C_SDA_OUT();
SCL_H;
SDA_H;
delay_us(5);
SDA_L;
delay_us(5);
SCL_L;
delay_us(2);
}
结束信号
结束信号简介SCL线为高电平期间,SDA线由低电平向高电平的变化表示终止信号,信号时序图:
注意的就是这里保持时间也是有一定限制的。
IO口模拟结束信号
//产生停止信号
void I2C_Stop(void)
{
I2C_SDA_OUT();
SCL_L;
SDA_L;
SCL_H;
delay_us(5);
SDA_H;
delay_us(6);
}
3.应答信号
应答,也叫响应。数据的传输必须要带有应答。在响应的时钟脉冲期间(也就是SCL在高电平的时候),发送器释放SDA线(释放SDA的意思就是将SDA拉为高电平,这里要注意的是,不能在S