I2C总线协议参考
1、AT24CXX注意事项
- 在产品中尽量使用WP写保护引脚;
- 程序中尽量减少不必要的AT24CXX的读写;
- 如果是大数据,尽量使用多字节读写,不要使用单字节读写;
2、AT24CXX设备地址
如上图所示,根据AT24CXX容量不同,设备地址也不同;如,
AT24C01/AT24C02:A0、A1、A2引脚作为7位设备地址的低三位,高4位固定为1010B,低三位A0、A1、A2(接GND为0,接VCC为1)确定了AT24CXX的设备地址,所以一根I2C线上最大可以接8个AT24CXX,地址为1010000B~1010111B。
AT24C04~AT24C16: A0、A1、A2只使用一部分,不用的悬空或者接地(数据手册中写的是悬空不接)。举例:AT24C04只用A2、A1引脚作为设备地址。另外一引脚P0(即原来A0的位置)没有使用,PCB中可悬空,发送地址中对应的这位(P0)用来写入页寻址的页面号,因此一根I2C线上最大可以接4个AT24C04,地址为101000xB~ 101011xB;同理,一根I2C线上最大可以接2个AT24C08,地址为10100xxB ~ 10101xxB;一根I2C线上最大可以接1个AT24C16,地址为1010xxxB ~ 1010xxxB;
AT24C32/AT24C64: 和AT24C01/AT24C02一样,区别是,发送数据地址变成16位。先发送设备地址高8位,再发送设备地址8位。
注意事项: 对AT24C32来说,WP置高,则只有四分之一受保护,即0x0C00-0x0FFF。也就是说保护区为1KBytes。对于低地址的四分之三,则不保护。所以,如果数据较多时,可以有选择地存储。不重要的数据则放在低四分之三区域,重要的数据则放在高四分之一区域
3、AT24CXX读写操作
3.1、AT24C16读写地址简介
AT24C16内部有16K bit的存储容量,可以存储2KByte的数据。这2K字节被放在128个页内,每页存放16个字节。
比如需要写数据到地址0x0643的,二进制为 0000 0110 0100 0011 ,注意这里位10:8即第一个字节的位3:1
1)第一字节器件地址0XAC(1010 1100,位7:4 (1010)是固定地址,位3:1(110)是页地址的高三位,位0(0)表示写操作);
2)第二字节操作地址0X43(0100 0011,0100是页地址的低四位,0011是页地址偏移量,即第100页内的第三个字节);
3.2、AT24C32读写举例
主机(MCU)向从机(AT24C32)写一个字节,流程如下:
- 主机启动开始信号;
- 主机发送从机地址(7bit)和写操作0(1bit),等待应答ACK;
- 从机发送应答ACK;
- 主机发送从机子地址高8位,等待应答ACK;
- 从机发送应答ACK;
- 主机发送从机子地址低8位,等待应答ACK;
- 从机发送应答ACK;
- 主机发送写数据8位,等待应答ACK;
- 从机发送应答ACK;
- 主机发送停止信号;
主机(MCU)向从机(AT24C32)读一个字节,流程如下:
- 主机启动开始信号;
- 主机发送从机地址(7bit)和写操作0(1bit),等待应答ACK;
- 从机发送应答ACK;
- 主机发送从机子地址高8位,等待应答ACK;
- 从机发送应答ACK;
- 主机发送从机子地址低8位,等待应答ACK;
- 从机发送应答ACK;
- 主机启动开始信号;
- 主机发送从机地址(7bit)和读操作1(1bit),等待应答ACK;
- 从机发送应答ACK;
- 从机发送一字节数据;
- 主机发送非应答信号NACK;
- 主机发送停止信号;
4、AT24CXX 使用注意事项
1、第一次使用时,上电给AT24CXX初始化,如在某个固定位置写 0xAA,或需要上电读写数据;在AT24CXX初始化或读写数据前应加一定的延时,等待电压稳定。否则在连续断电上电的情况下可能出现数据丢失;
2、读写数据时可以在读写失败时多读写几遍(即读写失败才重新读写,一次就读写成功可直接退出);
...
for(i = 0x00; i < 0x05; i++)
{
ack = I2C_WriteOneByte(WriteAddr,DataToWrite);
if(ack == I2C_ACK_OK) break;
Delay_ms(15);
WDT_FeedDog();
}
...
3、发送一字节响应失败后,一定要释放总线后再退出;
...
ack = SendByte(AT24CXX_ADDR | 0x01); /*发送设备地址 | 0x01,0x01表示读模式*/
if(ack == I2C_ACK_FAIL)
{
Stop_I2c(); /*字节发送失败,结束总线,退出函数*/
return I2C_ACK_FAIL;
}
...
4、连续写多个字节时应注意,一次写字节数只能写一页数据(一页的数量根据不同型号而不同),超出一页后会覆盖该页的前部数据;
5、数据写完后需要延时 5ms 左右,等待数据写进 AT24CXX;
6、读写 AT24CXX 数据地址时尽量使用宏定义而不用变量;
/*地址*/
#define IDSUM_BASE_ADDR 0x00
#define IDSUM_BACKUP_ADDR 0xF1
#define ID_BASE_ADDR 0x01
#define ID_BACKUP_ADDR 0x79
7、存储数据应做备份;
8、存储单个字节可做单字节校验;多个字节可用和校验;