- 半双工,意味着要使用开漏输出
- 由于弱上拉的作用,传输速率越快高电平上升得越缓慢,因此传输速率不能过快。标准速度100kHZ,高速400kHZ
- 有一主多从和多主多从模式
- 高位先行,比如AT24C128/256是16位地址,发送从机地址的时候要一个字节一个字节的发,这个时候因为是高位先行,因此先发高位地址
- 起始时序(SCL高电平期间SDA产生下降沿):先置SDA为高电平,然后置SCL为高电平,然后拉低SDA,然后在拉低SCL
- 终止时序(SCL高电平期间SDA产生上升沿):先拉底SDA,置SCL为高电平,再置SDA为高电平
- 接收方要在SCL高电平期间拿走数据,拿走后SCL变为低电平(SCL高电平期间SDA的电平不可以变化(有种说法是锁存数据),如果由低到高就变成终止信号,如果由高变低就变成起始信号)
- 主从机在传输数据期间,如需完成其他功能(如中断),主机可以主动拉低SCL,进入等待状态直到处理结束再释放SCL,数据传输会继续
- 主机接收数据:开始时应先释放SDA
- 主机发送数据:从机接收到数据应答前,主机应释放SDA,应答就相当于接收方给发送方发一位数据
- 连续写连续读:有一个地址指针,地址指针在读写寄存器的时候每读写完一个地址上的数据,地址指针就会指向这个地址的下一个地址,因此先读写寄存器某地址的一个字节数据后,地址指针就自动指向下一个该地址的下一个地址。接下来的读写就会操作地址指针指向的地址,因此连续写和连续读,当读写完第一个字节的时候就不需要重新指定寄存器地址了
- 主机不想读的时候要给从机发一个非应答信号,当读的数据量已知的时候通常这样处理
1 if (i != _usSize - 1)//_usSize 是读取的字节数 2 { 3 i2c_Ack(); /* 中间字节读完后,CPU产生ACK信号(驱动SDA = 0) */ 4 } 5 else 6 { 7 i2c_NAck(); /* 最后1个字节读完后,CPU产生NACK信号(驱动SDA = 1) */ 8 }
(该程序来自野火)
- 检查从机是否存在
1 uint8_t EEPROMIIC_CheckDevice(uint8_t _Address)
2 {
3 uint8_t ucAck;
4 EEPROMIIC_Start(); /* 发送启动信号 */
5 /* 发送设备地址+读写控制bit(0 = w, 1 = r) bit7 先传 */
6 EEPROMIIC_SendByte(EEPROM_WRITEADDRESS);
7 ucAck = EEPROMIIC_SlaveAck(); /* 检测设备的ACK应答 */
8 EEPROMIIC_Stop(); /* 发送停止信号 */
9 return ucAck;
10 }
- IIC理论上采用8位地址就可以挂127个从机,但是由于总线规定总线电容不能超过400PF,因为电容越大上升沿变化越平缓,影响信号质量,因此实际上不能超过8个从机
- 当前地址读,当前地址指的是上次操作寄存器的地址(地址指针就会加1),当前地址读的就是这个加1后的地址,时序是:起始+从机地址,读标志位+读出的数据,并没有指定读的从机地址
- IIC的传输速度由SCL的时钟频率决定