stm32f10x通过i2c读写at24c32

注:指南者才有i2c的硬件例程,mini只有软件i2c

看上去野火的例程来源于st官方,很多人对这个bsp库甚至stm32的i2c硬件都存在质疑,我在设计实验的时候没有发现软硬件存在什么大问题,程序上的一些小瑕疵是有,但瑕不掩瑜。同时还有人提出说为什么st把一个简单的通信协议写的这么复杂,其实我觉得单纯的通信部分是不复杂的,最难理解的可能在于实现page对齐部分,这部分对于初学者来讲很不友好,另外注释写的也不是很清晰。实际上对于入门来说,整个程序里面只要用到bytewrite这一个函数就够了。但是好处在于给了我们一种page对齐的算法,我认为这个算法本身的价值是大于i2c通信部分的。若以后换成其他只能按照block进行操作的存储器,该算法就派上用场了。嵌入式系统只是一个载体,算法和专业方向才是核心竞争力。

原程序中此处无需重启eeprom

原程序中此处少一个通信前的线路忙闲检测

之前在淘宝的一家店铺买过几个at24c02的转接模块,结果发来的模块没问题,但是芯片不是24c02,而是24c32,后者比前者略贵,貌似有赚到。然而甘蔗没有两头儿甜,示例程序直接用上就行不通了。02和32有几个地方不大一样:一是page大小不一样,前者是8字节,后者是32字节,不过这一点并不需要修改程序(这里就体现了例程中page对齐算法的高明之处了);二是容量不同,前者是256个字节,8-bit地址刚好够用,后者是4k字节,至少需要12-bit地址,这就导致原先的通信协议里,每次读写操作前都要先发送一个字节的内部word address行不通了,需要分开高低字节地址分两次发送,这个差异使得程序需要做一点调整。

24c02的读写流程

24c32的读写流程

具体方法就是每次发送读写地址的时候,由原来的发送一个字节地址,改为先后发送两次地址,先高后低,这两次地址组合起来就是实际欲读写地址。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/******** @AT24C32 **************** 03_1 Send EEPROM Internal @HIGH Word Address *******************************/	
I2C_SendData(EEPROM_I2C, (WriteAddr / 256)); // Send EEPROM internal word address -- high 8-bit
timeout = I2C_EVCHK_TIMEOUT_FLAG;
while (!I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) // Test EV8 and Clear
{
if((timeout--) == 0) return I2C_TIMEOUT_UserCallback(13);
}
/************************ 03_2 Send EEPROM Internal @LOW Word Address *******************************/
I2C_SendData(EEPROM_I2C, (WriteAddr % 256)); // Send EEPROM internal word address -- low 8-bit
timeout = I2C_EVCHK_TIMEOUT_FLAG;
while (!I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) // Test EV8 and Clear
{
if((timeout--) == 0) return I2C_TIMEOUT_UserCallback(8);
}

将原程序中要读写的256个字节改为512个进行测试。

串口显示

Author: Epiapoq
Link: http://epiapoq.github.io/2021/08/25/at24c32/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.