当前位置: 首页 > news >正文

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视而不见

代码获取、问题探讨及文章转载可私信。

☁ 愿你的生命中有够多的云翳,来造就一个美丽的黄昏。

🍎获取更多嵌入式资料可点击链接进群领取,谢谢支持!👇

点击领取更多详细资料


http://www.mrgr.cn/news/38723.html

相关文章:

  • SVG 滤镜:探索图形设计的无限可能
  • shp-write.js 导出shp数据:原理介绍及示例代码
  • FTP访问方式详解
  • C++ | Leetcode C++题解之第445题两数相加II
  • Java | Leetcode Java题解之第443题压缩字符串
  • 基于PI控制器的车辆行驶控制系统simulink建模与仿真
  • C++入门基础知识88(实例)——实例13【求一个数的阶乘】
  • 一天认识一个硬件之音响与音箱
  • Golang | Leetcode Golang题解之第445题两数相加II
  • tar命令:压缩、解压的好工具
  • undeclared identifier ‘UNITY_PREV_MATRIX_M‘ - Unity Shader自己写URP,引用内部 hlsl
  • linux环境下使用sqlplus访问远程oracle数据库
  • DAY17||654.最大二叉树 |617.合并二叉树 |700.二叉搜索树中的搜索 |
  • 0基础学习CSS(六)字体
  • The 2024 ICPC Asia East Continent Online Contest (II) K. Match(图计数dp 二分图匹配方案)
  • Cpp::STL—string类的使用与理解(下)(9)
  • 矩阵SVD分解中u,s,v的实际意义
  • Golang | Leetcode Golang题解之第443题压缩字符串
  • C++ | Leetcode C++题解之第443题压缩字符串
  • Android平台如何获取CPU占用率和电池电量信息