基于 BearPi Std 板从入门到放弃 - 后天篇(1)(I2C1 读取 光照强度), 使用同一个I2C接口访问EEPROM, 同时读取光照亮度
主芯片: STM32L431RCT6
LED : PC13 \ 推挽输出即可 \ 高电平点亮
串口: Usart1
I2C : I2C1
光照强度传感器:BH1750
EEPROM芯片 : AT24C02
AT2402C 基本描述, 2Kbit, 32Page, 每个Page 8 Bytes, 所以地址是0~255
结论
a. 结合 原理图,
A0 = 1; A1 = 0; A2 =0;
写的地址 = 10100010 = 0xA2
读的地址 = 10100011 = 0xA3
b. 2Kbit, 32Page, 每个Page 8 Bytes, 所以地址是0~255
#define AT24C02_WRITE_ADDRESS 0xA2
#define AT24C02_READ_ADDRESS 0xA3
/* 写单个字节 */
uint8_t AT24C02_Write_Byte(uint16_t addr, uint8_t *dat)
{
return HAL_I2C_Mem_Write(&hi2c1, AT24C02_WRITE_ADDRESS, addr, I2C_MEMADD_SIZE_8BIT, dat, 1, 0xffff);
}
/* 读取单个字节 */
uint8_t AT24C02_Read_Byte(uint16_t addr, uint8_t *buf)
{
return HAL_I2C_Mem_Read(&hi2c1, AT24C02_READ_ADDRESS, addr, I2C_MEMADD_SIZE_8BIT, buf, 1, 0xffff);
}
/* 读多个字节 */
uint8_t AT24C02_Read_Bytes(uint16_t addr, uint8_t *buf, uint16_t bufSize)
{
return HAL_I2C_Mem_Read(&hi2c1, AT24C02_READ_ADDRESS, addr, I2C_MEMADD_SIZE_8BIT, buf, bufSize, 0xffff);
}
int main()
{
...
uint8_t res = 0;
uint8_t datTemp = 0;
/* 写完整个EEPROM */
for (int i = 0; i < 256; ++i)
{
datTemp = i;
res = AT24C02_Write_Byte(i, &datTemp);
if (res)
{
printf("Faile To Write Address %d!\r\n", i);
}
HAL_Delay(10); // 写延时, 不然会失败
}
/* 读完整个EEPROM */
for (int i = 0; i < 256; ++i)
{
res = AT24C02_Read_Byte(i, &datTemp);
if (res)
{
printf("Faile To ReadAddress %d!\r\n", i);
}
else
{
printf("Address: %d, Value: %d\r\n", i, datTemp);
}
}
while(1)
{
...
}
}
Note:
可以扩展 WritePage, 1 Page 8 Bytes, 可以一次性写8Bytes
例如
0(地址), 8Bytes数据; // 第一页
8(地址), 8Bytes数据; // 第二页
…
24(地址), 8Bytes数据; // 第三页
/* 接口可以按页码, 简单写下 */
uint8_t writePage(uint_8 pageNum, uint_8 *dat, uint_16 datSize)
{
uint16_t addr = 0;
if (pageNum < 0 || pageNum >= 32)
return 1; // HAL_ERROR;
addr = pageNum * 8; // 每页8Bytes
return HAL_I2C_Mem_Write(&hi2c1, AT24C02_READ_ADDRESS, addr, I2C_MEMADD_SIZE_8BIT, dat, datSize, 0xffff);
}
BearPi I2C1 完整项目工程, 包含两份芯片datasheet