STM32 通过软件模拟 I2C 驱动 24Cxx 系列存储器
在嵌入式系统中,EEPROM是一种常用的非易失性存储器,用于存储小量的数据。24Cxx系列是比较常见的EEPROM芯片,本文将介绍如何通过STM32的软件模拟I2C总线来驱动24Cxx系列存储器。
一、I2C通信协议简介
I2C(Inter-Integrated Circuit)是一种串行通信协议,用于微控制器和其他设备之间的通信。它只需要两条线:SCL(时钟线)和SDA(数据线)。I2C协议支持多主设备和多从设备,通过地址来区分不同的从设备。
二、24Cxx系列存储器特性
24Cxx系列存储器是一系列CMOS EEPROM,具有以下特性:
- 低功耗,适合便携式设备。
- 多种容量选择,如24C02(256字节)、24C04(512字节)、24C08(1K字节)等。
- 支持I2C通信协议。
- 具有页写能力,可以快速写入数据。
三、硬件连接
STM32单片机通过软件模拟I2C通信,连接24Cxx系列存储器只需要两条GPIO引脚,一个作为SCL,另一个作为SDA。
四、软件实现
4.1 初始化I2C GPIO端口
首先,需要配置两个GPIO引脚作为I2C的SCL和SDA线。
void I2C_GPIO_Init() {GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);// 设置I2C引脚输出高电平GPIO_SetBits(GPIOB, GPIO_Pin_6 | GPIO_Pin_7);
}
4.2 I2C起始信号
I2C通信开始时,需要发送一个起始信号。
void I2C_Start() {I2C_SDA_H();I2C_SCL_H();I2C_SDA_L();I2C_Delay();I2C_SCL_L();
}
4.3 I2C停止信号
数据传输完成后,发送停止信号。
void I2C_Stop() {I2C_SDA_L();I2C_SCL_H();I2C_Delay();I2C_SDA_H();
}
4.4 发送字节
发送一个字节到EEPROM,并等待应答。
void I2C_SendByte(uint8_t byte) {for (uint8_t i = 0; i < 8; i++) {if (byte & 0x80) {I2C_SDA_H();} else {I2C_SDA_L();}byte <<= 1;I2C_SCL_H();I2C_Delay();I2C_SCL_L();}I2C_Ack();
}
4.5 读取字节
从EEPROM读取一个字节。
uint8_t I2C_ReadByte() {uint8_t byte = 0;I2C_SDA_H(); // 使能SDA线for (uint8_t i = 0; i < 8; i++) {byte <<= 1;I2C_SCL_H();if (I2C_SDA_Read()) {byte |= 0x01;}I2C_SCL_L();}I2C_NAck();return byte;
}
4.6 写入EEPROM
将数据写入EEPROM的指定地址。
void AT24Cxx_WriteByte(uint8_t addr, uint8_t data) {I2C_Start();I2C_SendByte(AT24C02_ADDR << 1 | 0); // 发送写命令I2C_SendByte(addr); // 发送地址I2C_SendByte(data); // 发送数据I2C_Stop();
}
4.7 读取EEPROM
从EEPROM的指定地址读取数据。
uint8_t AT24Cxx_ReadByte(uint8_t addr) {uint8_t data = 0;I2C_Start();I2C_SendByte(AT24C02_ADDR << 1 | 0); // 发送写命令I2C_SendByte(addr); // 发送地址I2C_Start();I2C_SendByte(AT24C02_ADDR << 1 | 1); // 发送读命令data = I2C_ReadByte();I2C_Stop();return data;
}
五、测试程序
编写测试程序验证读写功能。
int main() {I2C_GPIO_Init();uint8_t test_data = 0x55;uint8_t read_data = 0;// 测试写入AT24Cxx_WriteByte(0x00, test_data);// 测试读取read_data = AT24Cxx_ReadByte(0x00);if (read_data == test_data) {printf("Read and write test passed.\n");} else {printf("Read and write test failed.\n");}while (1) {// 循环中可以添加其他操作}
}
六、总结
通过软件模拟I2C总线,我们可以在没有硬件I2C支持的情况下,实现对24Cxx系列存储器的读写操作。这种方法虽然效率不如硬件I2C,但在某些特定场合下可以作为一种替代方案。
✅作者简介:热爱科研的嵌入式开发者,修心和技术同步精进
❤欢迎关注我的知乎:对error视而不见
代码获取、问题探讨及文章转载可私信。
☁ 愿你的生命中有够多的云翳,来造就一个美丽的黄昏。
🍎获取更多嵌入式资料可点击链接进群领取,谢谢支持!👇
点击领取更多详细资料