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

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

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

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

点击领取更多详细资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI_Guru人工智能

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值