前言
软件模拟I2C是指利用单片机的GPIO口模拟I2C总线进行通信,这种方式不需要专门的I2C外设硬件支持,仅通过软件实现I2C的各种通信协议,具有较高的灵活性和兼容性。
起始信号,其具体步骤如下:
- 把SDA置为高电平。
- 把SCL置为高电平,等待一个半个I2C时钟周期的时间,确保I2C总线空闲。
- 把SDA置为低电平,表示发出起始信号。
- 把SCL置为低电平,为发送第一个字节做准备。
结束信号的步骤如下:
- 把SDA置为低电平,表示发出结束信号。
- 把SCL置为高电平,待半个I2C时钟周期后,把SDA设置为高电平,表示结束传输。
- 软件I2C的读操作
写操作的主体部分,具体步骤如下:
- 发送开始信号
- 发送设备地址和读写控制位,根据具体设备的地址和I2C协议可知道读写控制位在设备地址的最后一位。通常读操作控制位为1,写操作控制位为0。
- 响应设备给出的应答信号。
- 将要写入的数据发送给设备。
- 响应设备给出的应答信号。
- 重复步骤,直到写入所有要发送的数据。
- 发送结束信号。
读操作的主体部分,具体步骤如下:
- 发送开始信号
- 发送设备地址和读写控制位,并响应从设备的应答信号。
- 发送要读取的寄存器地址,并响应从设备的应答信号。
- 发送开始信号
- 发送读取命令,并等待从设备的应答信号。
- 读取从设备发送的数据,并给出应答信号或非应答信号。
- 重复步骤,直到读取到所有所需的数据。
- 发送结束信号。
代码如下:
读一个字节:
int8_t i2cRead(uint8_t address)
{
uint8_t val;
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(address);
I2CWaitAck();
I2CStart();
I2CSendByte(0xa1);
I2CWaitAck();
val = I2CReceiveByte();
I2CWaitAck();
I2CStop();
return val;
}
写一个字节:
void i2cWrite(uint8_t address, uint8_t val)
{
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(address);
I2CWaitAck();
I2CSendByte(val);
I2CWaitAck();
I2CStop();
}
值得注意的是,开发板上的EEP芯片是8位的只能写0-255,数据超出的话,可以考虑拆分为低八位,高八位。(嫌麻烦的直接把数字转成字符串存)。