根据AT24C02的 Datasheet 可知AT24C02有2K bit,即256B,分为32页,每页8个字节,结合数据手册和原理图可以得知,板载AT24C02的读地址为0xA2
,写地址为0xA3
:
#define AT24C02_ADDR_WRITE 0xA2
#define AT24C02_ADDR_READ 0xA3
- MSB(Most Significant Bit):即最高有效位,是二进制数中权重最大的位。在一个二进制数里,它位于最左边,对数值大小的影响最大。例如,在二进制数
1010
中,最左边的1
就是 MSB,它代表的权重是 23=8。 - LSB(Least Significant Bit):也就是最低有效位,是二进制数中权重最小的位。它处于二进制数的最右边,对数值大小的影响最小。比如在二进制数
1010
中,最右边的0
就是 LSB,它代表的权重是 20=1。
图中展示的是 AT24C02(I2C 接口的 EEPROM 芯片)的 “字节写” 操作时序,以下是对该时序的详细解释:
1. 起始信号(START)
• 作用:主设备通过拉低 SDA 线(在 SCL 为高电平时)发起通信,标志一次 I2C 传输的开始。
• 图示:图中 “SDA LINE” 波形的第一个跳变,由高变低,触发起始条件。
2. 设备地址(DEVICE ADDRESS)
• 内容:7 位 AT24C02 设备地址(MSB 先传输) + 1 位读写控制位(R/W)。写操作时,R/W = 0。
• 意义:主设备通过发送设备地址,选中总线上的 AT24C02 从设备,告知其即将进行写操作。
3. 字地址(WORD ADDRESS)
• 内容:8 位地址(MSB 到 LSB 依次传输),用于指定 AT24C02 中要写入数据的存储单元位置。
• 作用:AT24C02 有 256 字节存储空间,需通过字地址精准定位目标存储单元。
4. 数据(DATA)
• 内容:主设备发送的 8 位数据(MSB 先,LSB 后),即实际写入 AT24C02 的数据内容。
• 传输:数据跟随在字地址之后,按 I2C 协议的字节传输格式发送。
5. 应答位(ACK)
• 机制:每传输完一个字节(设备地址、字地址、数据),接收方(AT24C02)需在第 9 个时钟周期拉低 SDA 线,返回 ACK 信号,表示成功接收。
• 图示:每个字节传输后标注的 “ACK”,体现 I2C 通信的应答确认机制。
6. 停止信号(STOP)
• 作用:主设备通过拉高 SDA 线(在 SCL 为高电平时)结束本次通信,释放 I2C 总线。
• 图示:图中最后 SDA 线由低变高的跳变,标志字节写操作完成。
完整流程总结
主设备先发送起始信号,接着发送含写控制位的设备地址,等待 AT24C02 应答;再发送字地址(指定存储位置),再次等待应答;最后发送数据字节,待 AT24C02 应答后,主设备发送停止信号,完成一次字节写操作。整个过程严格遵循 I2C 协议的时序规范,确保数据准确写入 AT24C02 的指定地址。
看原理图
扩展板
核心板引脚
STM32Cubemax
写入
/*** @brief AT24C02任意地址写一个字节数据* @param addr —— 写数据的地址(0-255)* @param dat —— 存放写入数据的地址* @retval 成功 —— HAL_OK
*/
uint8_t At24c02_Write_Byte(uint16_t addr, uint8_t* dat)
{return HAL_I2C_Mem_Write(&hi2c1, AT24C02_ADDR_WRITE, addr, I2C_MEMADD_SIZE_8BIT, dat, 1, 0xFFFF);
}
读
/*** @brief AT24C02任意地址读一个字节数据* @param addr —— 读数据的地址(0-255)* @param read_buf —— 存放读取数据的地址* @retval 成功 —— HAL_OK
*/
uint8_t At24c02_Read_Byte(uint16_t addr, uint8_t* read_buf)
{return HAL_I2C_Mem_Read(&hi2c1, AT24C02_ADDR_READ, addr, I2C_MEMADD_SIZE_8BIT, read_buf, 1, 0xFFFF);
}
测试
uint8_t write_dat = 0xa5;uint8_t recv_buf = 0;if(HAL_OK == At24c02_Write_Byte(10,&write_dat)){printf("Write ok\n");}else{printf("Write fail\n");}HAL_Delay(50); //写一次和读一次之间需要短暂的延时if(HAL_OK == At24c02_Read_Byte(10,&recv_buf)){printf("Read ok, recv_buf = 0x%02X\n", recv_buf);}else{printf("Read fail\n");}
串口测试
这款芯片的读写比较简单 只需要配置好相关的协议就可以直接进行读写操作