• 半双工,意味着要使用开漏输出
  • 由于弱上拉的作用,传输速率越快高电平上升得越缓慢,因此传输速率不能过快。标准速度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的时钟频率决定
posted on 2024-01-31 21:49  小凉拖  阅读(16)  评论(0编辑  收藏  举报