HRTOS 4.0 驱动库:06_Storage 存储设备驱动——24C02 EEPROM与I²C驱动开发

在 51 单片机(8051)嵌入式系统开发中,RAM 通常用于程序运行过程中的临时数据保存,而 EEPROM 则可以用于保存需要掉电保持的重要参数,例如设备配置、校准数据、用户参数以及系统运行状态等。

HRTOS 4.0 Driver Library 提供了独立的 06_Storage 存储设备驱动模块 ,目前主要针对常用的 24C02 EEPROM,并提供底层软件 I²C 通信实现。

本文将介绍 HRTOS 4.0 06_Storage 模块的整体结构、24C02 EEPROM 驱动、软件 I²C 实现、API 接口、硬件连接以及实际使用方法。

通过该模块,可以在 51 单片机实时操作系统环境下更加方便地实现 EEPROM 数据存储功能。


一、HRTOS 4.0 06_Storage 模块概述

06_Storage 是 HRTOS Driver Library 中面向存储设备的驱动模块。

当前主要支持:

  • 24C02 EEPROM

  • 软件模拟 I²C 通信

公共头文件:

复制代码
#include "HRTOS_Storage.h"

驱动实现依赖 HRTOS 硬件抽象层:

复制代码
#include "hrtos_hal.h"

I²C 延时使用 8051 编译环境提供的:

复制代码
#include <intrins.h>

并通过 _nop_() 实现基础时序延时。

当前模块主要由两部分组成:

复制代码
06_Storage
    │
    └── EEPROM
          │
          └── EEPROM-IIC
                ├── 24C02 EEPROM 驱动
                └── 软件 I²C 底层实现

二、24C02 EEPROM 简介

24C02 是嵌入式系统中非常常见的串行 EEPROM 器件。

其存储容量为:

复制代码
2Kbit = 256 Byte

内部地址范围:

复制代码
0x00 ~ 0xFF

因此可以通过一个 8 位地址访问整个 EEPROM 存储空间。

在 51 单片机应用中,24C02 可以用于保存:

  • 系统配置参数

  • 用户设置

  • 设备编号

  • 校准参数

  • 运行参数

  • 掉电保存数据

HRTOS 4.0 当前提供的是单字节读写驱动


三、24C02 文件组成

当前 EEPROM 驱动目录:

复制代码
EEPROM/EEPROM-IIC/
├── 24c02_read.c
├── 24c02_write.c
├── i2c.c
├── i2c_delay.c
├── i2c_read_byte.c
├── i2c_start.c
├── i2c_stop.c
└── i2c_write_byte.c

其中:

24C02 驱动

复制代码
24c02_read.c
24c02_write.c

负责实现 EEPROM 的上层读写操作。

I²C 底层

复制代码
i2c_delay.c
i2c_read_byte.c
i2c_start.c
i2c_stop.c
i2c_write_byte.c

负责软件模拟 I²C 总线通信。

i2c.c 当前主要用于头文件引用,本身没有实际功能实现。

这种结构将 EEPROM 操作和 I²C 总线操作进行了分层。


四、24C02 硬件连接

当前 24C02 EEPROM 使用软件 I²C。

引脚定义:

复制代码
sbit EEPROM_SCL = P2^1;
sbit EEPROM_SDA = P2^0;

对应关系:

信号 51 单片机引脚 功能
SDA P2.0 I²C 数据
SCL P2.1 I²C 时钟

因此硬件连接为:

复制代码
24C02 SDA ─── P2.0
24C02 SCL ─── P2.1

同时需要注意 I²C 总线的电气特性。

SDA 和 SCL 通常需要外部上拉电阻,例如:

复制代码
4.7kΩ ~ 10kΩ

当前驱动没有实现内部上拉,因此实际硬件电路需要提供合适的外部上拉。


五、24C02 地址空间

24C02 总容量为:

复制代码
2Kbit

换算:

复制代码
2Kbit ÷ 8 = 256 Byte

所以内部存储地址:

复制代码
0x00 ~ 0xFF

也就是:

复制代码
0 ~ 255

驱动接口使用:

复制代码
unsigned char

作为 EEPROM 内部地址类型。

例如:

复制代码
eeprom_24c02_write(0x10, 0x55);

表示向 EEPROM 内部地址 0x10 写入 0x55


六、24C02 I²C 器件地址

当前驱动使用固定的 24C02 器件地址:

复制代码
写地址:0xA0
读地址:0xA1

二进制表示:

复制代码
0xA0 = 1010 0000
0xA1 = 1010 0001

其中最低位用于表示读写方向。

当前驱动按照固定地址实现,因此应用层不需要额外配置器件地址。

需要注意,这里所说的 0xA0/0xA1 是驱动当前使用的 8 位 I²C 地址形式,并不是通常所说的 7 位从机地址表示方式。


七、24C02 写入驱动

7.1 eeprom_24c02_write()

函数原型:

复制代码
void eeprom_24c02_write(unsigned char addr, unsigned char dat);

功能:

向指定的 EEPROM 地址写入一个字节。

参数:

复制代码
addr:EEPROM 地址,0x00~0xFF
dat :写入数据,0x00~0xFF

基本通信过程:

复制代码
I²C START
    ↓
发送 0xA0
    ↓
发送 EEPROM 内部地址
    ↓
发送数据
    ↓
I²C STOP
    ↓
等待 EEPROM 写周期

例如:

复制代码
eeprom_24c02_write(0x10, 0x55);

表示:

复制代码
EEPROM[0x10] = 0x55

八、24C02 读取驱动

8.1 eeprom_24c02_read()

函数原型:

复制代码
unsigned char eeprom_24c02_read(unsigned char addr);

功能:

读取 EEPROM 指定地址中的一个字节。

参数:

复制代码
addr:EEPROM 地址,0x00~0xFF

返回:

复制代码
0x00~0xFF

读取过程采用随机读取方式:

复制代码
I²C START
    ↓
发送写地址 0xA0
    ↓
发送 EEPROM 内部地址
    ↓
重复 START
    ↓
发送读地址 0xA1
    ↓
读取一个字节
    ↓
发送 NACK
    ↓
I²C STOP

例如:

复制代码
unsigned char data;

data = eeprom_24c02_read(0x10);

即可读取 EEPROM 地址 0x10 中保存的数据。


九、24C02 完整读写示例

下面是一个简单的 EEPROM 数据保存与读取示例:

复制代码
#include "HRTOS_Storage.h"

void main(void)
{
    unsigned char data;

    // 写入数据
    eeprom_24c02_write(0x00, 0x12);
    eeprom_24c02_write(0x01, 0x34);
    eeprom_24c02_write(0x02, 0x56);
    eeprom_24c02_write(0x03, 0x78);

    // 等待 EEPROM 写周期
    os_delay_ms(10);

    // 读取数据
    data = eeprom_24c02_read(0x00);
    data = eeprom_24c02_read(0x01);
    data = eeprom_24c02_read(0x02);
    data = eeprom_24c02_read(0x03);

    while(1)
    {
        // 主循环
    }
}

实际应用中可以根据需要,将读取出来的数据进一步交给 HRTOS 任务进行处理。

例如:

复制代码
EEPROM
  ↓
读取配置
  ↓
HRTOS 任务
  ↓
应用逻辑
  ↓
控制设备

这样 EEPROM 就可以作为系统参数的非易失性存储空间。


十、软件 I²C 底层实现

24C02 驱动的底层通信采用软件模拟 I²C

也就是说,驱动并没有依赖单片机专用 I²C 外设,而是直接通过 GPIO 控制:

复制代码
SDA
SCL

实现 I²C 总线时序。

这对于一些没有硬件 I²C 外设的 51 单片机尤其方便。


十一、I²C 延时

当前 I²C 延时函数:

复制代码
eeprom_delay();

底层通过 _nop_() 实现:

复制代码
_nop_();
_nop_();

因此实际延时时间与:

  • 单片机系统时钟

  • 编译器

  • 指令执行周期

等因素有关。

软件 I²C 的实际通信速度也会受到这一延时函数影响。

因此当前驱动的 I²C 时钟频率并不是通过一个固定的硬件分频寄存器产生,而是由软件时序决定。


十二、I²C 起始条件

内部函数:

复制代码
eeprom_i2c_start();

负责产生 I²C START 条件。

基本时序:

复制代码
SDA = 1
    ↓
延时
    ↓
SCL = 1
    ↓
延时
    ↓
SDA = 0
    ↓
延时
    ↓
SCL = 0

START 条件的核心就是:

在 SCL 保持高电平时,让 SDA 从高电平变为低电平。

随后总线进入数据传输状态。


十三、I²C 停止条件

内部函数:

复制代码
eeprom_i2c_stop();

负责产生 STOP 条件。

基本过程:

复制代码
SDA = 0
    ↓
延时
    ↓
SCL = 1
    ↓
延时
    ↓
SDA = 1

即:

在 SCL 为高电平期间,让 SDA 从低电平变为高电平。

这表示当前 I²C 通信结束。


十四、I²C 字节写入

内部函数:

复制代码
unsigned char eeprom_i2c_write_byte(unsigned char dat);

用于向 I²C 总线发送一个字节。

数据采用:

复制代码
MSB First

即最高位首先发送。

每一位数据大致经过:

复制代码
SDA = 数据位
    ↓
延时
    ↓
SCL = 1
    ↓
延时
    ↓
SCL = 0
    ↓
延时

发送完 8 位数据之后,释放 SDA,并进入 ACK 检测阶段。


十五、I²C ACK 检测

当前 I²C 底层实现包含 ACK 检测。

发送一个字节之后:

复制代码
释放 SDA
    ↓
SCL = 1
    ↓
读取 SDA

如果:

复制代码
SDA = 0

表示从设备返回 ACK。

如果:

复制代码
SDA = 1

则表示没有收到 ACK。

当前实现还包含超时检测,最多循环约 200 次。

返回值:

复制代码
1 → 收到 ACK
0 → 未收到 ACK / 超时

因此底层 I²C 字节写函数具备一定的通信异常检测能力。


十六、I²C 字节读取

内部函数:

复制代码
unsigned char eeprom_i2c_read_byte(void);

用于从 I²C 总线读取一个字节。

读取过程中:

复制代码
SCL = 1
    ↓
读取 SDA
    ↓
数据左移
    ↓
SCL = 0

连续执行 8 次,最终得到完整的一个字节。

读取函数本身不负责最终 ACK/NACK 控制,由上层调用者根据通信流程进行处理。

对于 24C02 单字节随机读取,读取完成后发送 NACK,随后产生 STOP 条件。


十七、06_Storage API 汇总

当前模块公开接口包括 EEPROM 操作接口和 I²C 底层接口。

类型 API 功能 返回值
24C02 eeprom_24c02_write() 写入一个字节
24C02 eeprom_24c02_read() 读取一个字节 unsigned char
I²C eeprom_i2c_start() I²C 起始条件
I²C eeprom_i2c_stop() I²C 停止条件
I²C eeprom_i2c_write_byte() I²C 写入字节 unsigned char
I²C eeprom_i2c_read_byte() I²C 读取字节 unsigned char
I²C eeprom_delay() I²C 时序延时

当前按照接口清单统计,共有:

7 个公开 API。

其中:

复制代码
24C02:
2 个接口

I²C:
5 个接口

虽然底层 I²C 接口目前也在头文件中公开,但正常应用开发时,更推荐直接使用:

复制代码
eeprom_24c02_write();
eeprom_24c02_read();

而不是直接操作底层 I²C 时序函数。


十八、24C02 驱动的特点

当前 HRTOS 4.0 24C02 驱动具有以下特点。

1. 接口简单

应用程序不需要了解完整的 I²C 时序,只需要:

复制代码
eeprom_24c02_write(addr, dat);

或者:

复制代码
data = eeprom_24c02_read(addr);

即可完成 EEPROM 基本操作。

2. 软件 I²C

不依赖专用 I²C 外设,可以通过普通 GPIO 实现通信。

这对于传统 51 单片机尤其有意义。

3. 单字节操作

当前驱动以单字节为基本操作单位:

复制代码
1 次写入 → 1 Byte
1 次读取 → 1 Byte

实现简单,也比较适合作为 24C02 驱动的基础版本。

4. 分层设计

整体结构可以理解为:

复制代码
应用程序
   ↓
eeprom_24c02_read/write
   ↓
I²C 底层接口
   ↓
GPIO
   ↓
24C02

这种分层结构使 EEPROM 操作和总线时序之间具有比较明确的职责划分。


十九、源码与接口一致性检查

目前对 06_Storage 模块的源码和接口进行了对应检查。

已经确认:

  • HRTOS_Storage.h 中声明的公开 API 均有对应实现

  • 函数名称与实现一致

  • 参数类型与实现一致

  • 返回值类型与实现一致

  • EEPROM 引脚定义与源码一致

  • I²C 器件地址与源码一致

  • EEPROM 读写流程与源码一致

  • I²C 起始和停止时序与实现一致

  • ACK 检测逻辑与底层实现一致

  • 示例代码中的主要接口均为真实存在的 API

文件覆盖情况:

复制代码
EEPROM-IIC:

8 个源文件
7 个公开 API

因此当前模块的基本驱动结构已经建立完成。


二十、当前版本需要注意的问题

作为驱动库的一部分,除了能够实现基本功能之外,还需要考虑硬件可靠性和接口完整性。

当前版本有几个值得注意的地方。

1. EEPROM 写周期

24C02 在执行写操作之后,需要一定时间完成内部 EEPROM 写入。

当前 eeprom_24c02_write() 使用的固定延时比较短,因此如果连续快速执行:

复制代码
eeprom_24c02_write();
eeprom_24c02_write();

可能需要额外等待写周期。

实际应用中建议根据器件规格增加适当的等待时间,例如:

复制代码
os_delay_ms(5);

或者:

复制代码
os_delay_ms(10);

更完善的实现则可以采用 ACK Polling 判断 EEPROM 是否已经完成内部写周期。


二十一、当前暂未实现的功能

当前 24C02 驱动主要定位于基础单字节读写,因此暂未实现一些扩展功能。

包括:

  • 页写

  • 连续读取

  • 连续写入

  • ACK Polling

  • 更完整的错误返回机制

例如目前:

复制代码
void eeprom_24c02_write(unsigned char addr,
                        unsigned char dat);

没有返回写入成功或失败状态。

如果后续进一步增强驱动,可以考虑:

复制代码
unsigned char eeprom_24c02_write(...);

通过返回值让应用程序判断操作结果。


二十二、I²C 外部上拉

I²C 与普通推挽 GPIO 通信不同,SDA 和 SCL 通常需要通过上拉电阻恢复高电平。

因此实际连接 24C02 时,应注意:

复制代码
VCC
 │
上拉电阻
 │
SDA ─────────────── 24C02 SDA
 │
P2.0

VCC
 │
上拉电阻
 │
SCL ─────────────── 24C02 SCL
 │
P2.1

常见上拉电阻可以根据实际电路选择,例如:

复制代码
4.7kΩ

或者:

复制代码
10kΩ

具体阻值需要结合总线速度、供电电压、线路电容等实际条件确定。


二十三、软件 I²C 与实时操作系统

HRTOS 4.0 的 06_Storage 使用软件模拟 I²C,因此 I²C 的时序由软件代码直接控制。

这意味着在 HRTOS 环境中使用时,需要关注实时系统的任务调度和中断对软件时序的影响。

当前实现没有在 I²C 操作过程中专门关闭中断,因此实际系统中应根据:

  • CPU 主频

  • I²C 时序要求

  • 中断响应时间

  • 系统任务调度

  • 实际总线波形

进行验证。

对于要求严格的 I²C 时序,可以进一步结合逻辑分析仪对:

复制代码
SCL
SDA

进行实际测量。

这也是嵌入式驱动开发中非常重要的一步:

代码逻辑正确,并不等于实际总线时序一定满足硬件要求。


二十四、HRTOS 4.0 中的存储驱动

对于一个 51 单片机实时操作系统而言,存储设备驱动承担的是数据持久化功能。

例如可以建立这样的应用:

复制代码
        HRTOS 4.0
             │
       ┌─────┴─────┐
       │           │
    系统任务     控制任务
       │           │
       └─────┬─────┘
             │
        06_Storage
             │
        24C02 EEPROM
             │
        非易失性数据

系统启动时可以从 EEPROM 读取配置:

复制代码
EEPROM
  ↓
读取配置参数
  ↓
初始化系统
  ↓
HRTOS任务运行

运行过程中也可以将修改后的参数重新保存:

复制代码
用户修改参数
     ↓
应用任务
     ↓
EEPROM写入
     ↓
掉电保持

这样,24C02 就不再只是一个简单的实验器件,而可以成为整个 51 单片机应用系统中的参数存储模块。


二十五、HRTOS 4.0 与 51 单片机驱动开发

HRTOS 4.0 Driver Library 的一个重要目标,就是将 51 单片机常见硬件资源逐步整理成更加统一的驱动接口。

06_Storage 所解决的问题,就是将:

复制代码
24C02
   ↓
I²C
   ↓
GPIO

这一套底层硬件操作封装起来。

对于应用程序而言,只需要关注:

复制代码
eeprom_24c02_write(0x10, 0x55);

data = eeprom_24c02_read(0x10);

而不需要每次重新编写:

  • I²C START

  • I²C STOP

  • 字节发送

  • ACK 检测

  • 字节读取

  • EEPROM 器件地址

  • EEPROM 内部地址

这正是 51 单片机驱动开发逐步工程化的重要过程。

从操作系统角度来看,Driver Library 也是 HRTOS 与实际硬件之间的重要连接层。


二十六、HRTOS 官方网站

HRTOS 是一个面向 51 单片机 / 8051 的实时操作系统项目,持续完善操作系统内核、API、驱动库、实验例程以及技术文档。

如果希望进一步了解 HRTOS 4.0、Driver Library、API 文档以及 51 单片机实时操作系统相关内容,可以访问:

HRTOS 官方网站:

HRTOS 官方网站

这里可以进一步了解 HRTOS 项目的整体定位以及相关开发资料。


二十七、总结

HRTOS 4.0 Driver Library 06_Storage 模块目前主要提供 24C02 EEPROM 存储驱动和软件 I²C 底层通信功能

主要特点包括:

  • 支持 24C02 2Kbit EEPROM

  • 支持 256 字节地址空间

  • 支持单字节读取

  • 支持单字节写入

  • 使用软件模拟 I²C

  • 支持 I²C ACK 检测

  • 提供独立的 I²C 底层实现

  • 使用统一的存储设备驱动接口

当前模块共提供 7 个公开 API,其中 24C02 上层接口 2 个,I²C 底层接口 5 个。

虽然当前版本仍然属于基础存储驱动,尚未加入页写、连续读写和 ACK Polling 等功能,但已经建立了从 HRTOS 应用层 → EEPROM 驱动 → 软件 I²C → 51 单片机 GPIO → 24C02 的完整基本链路。

对于 51 单片机和 8051 开发者来说,这类驱动不仅可以用于 EEPROM 实验,也可以作为学习 I²C 总线、非易失性存储以及嵌入式驱动开发 的基础。

随着 HRTOS 4.0 Driver Library 的持续完善,更多常用硬件设备可以在统一的驱动接口下接入 HRTOS 实时操作系统,从而进一步完善 51 单片机的软件生态。

HRTOS ------ 面向 8051/51 单片机的实时操作系统。

访问 HRTOS 官方网站


关键词

HRTOS 4.0、HRTOS、51单片机、8051、51单片机操作系统、实时操作系统、嵌入式操作系统、驱动开发、单片机驱动、存储设备驱动、24C02、EEPROM、I²C、软件I²C、STC12C5A60S2、嵌入式开发

相关推荐
周洲08301 小时前
STM32 串口不定长接收|空闲中断 IDLE 方案,无固定帧长限制,项目实战
stm32·单片机·嵌入式硬件
我和头发拼了4 小时前
STM32--10硬件读写MPU6050
stm32·单片机·嵌入式硬件
雨田言炎5 小时前
2026/9/5 C复习笔记(一)
c语言·笔记
KFCgrandpahhh5 小时前
rk3576点灯
linux·驱动开发
糖糖单片机设计5 小时前
基于STM32的鱼缸水质检测系统
stm32·单片机·嵌入式硬件
HRTOS5 小时前
HRTOS 4.0 正式发布:Driver Library 基础外设驱动模块介绍
驱动开发·单片机·嵌入式硬件·51单片机
染予6 小时前
20个点位下发该如何正常操作?
单片机·嵌入式硬件
wuyk5556 小时前
从零吃透 MQTT 通信|第 5 章 MQTT 心跳保活机制深度优化,断线检测与智能自动重连
c语言·开发语言·stm32·学习
jianqiang.xue7 小时前
ESP-IDF保姆级入门23|MQTT物联网通信全解:发布订阅模式/QoS等级/遗嘱消息/主题设计/断线重连,掌握工业级标准消息通信
stm32·单片机·mcu·物联网·51单片机·iot