使用I2C EEPROM作为Arduino上的文件系统





准备工作:
材料:
- 该库和测试程序适用于任何Arduino设备,无论是3.3V还是5V系统。它已经在多个平台如Arduino、ESP、Raspberry Pi Pico上进行了测试。
- 需要一个小的面包板和一些导线来连接EEPROM。
- EEPROM可作为模块、芯片或集成在实时时钟中提供。最常见的模块要么是图片右侧带有可配置I2C地址和写保护功能的那种,要么是中间固定地址的那种。你可以使用这个库与这些设备中的任何一个。
- 你需要Arduino IDE。我使用的是1.8.15版本。此外,你需要从以下链接下载库:
- https://github.com/slviajero/EepromFS
- 并将其整合到你的Arduino库中。
连接EEPROM




大多数模块都在电路板上印有针形图案。将Arduino的SDA脚(在UNO上为A4)与模块的SDA脚和SCL脚(在UNO上的A5)连接。也连接电源。几乎所有的eeprom都可以在5V的电压下运行。有一些模型的最小电压降为1.7V。这些是24FCxxx类型,xxx以位表示EEPROM大小。相当便宜的24Cxxx需要在2.7V到5V之间。
这些模块的I2C地址在0x50到0x57之间。在上述可配置模块上,包括写保护WP在内的所有跳线都应该打开。这样,该地址就会被设置为0x50。
EEPROM芯片也可以直接连接,使地址和WP引脚打开。不需要I2C上拉电阻。将地址引脚拉到5V将改变I2C地址。拉出WP将激活写入保护。SDA连接到针脚5,SCL连接到模块的针脚6。接通针脚8(VCC)和针脚4(GND)。
时钟芯片,根据不同的时钟模型,也有不同的地址。
非常常见的HW-084型号有0x57作为其4kB EEPROM的默认地址。这些模块都是矩形的。稍小的二次“小RTC”模块使用0x50。这两个模块都可以通过焊接跨接连接来进行配置。
下载软件

下载并安装EEPROM文件系统库
https://github.com/slviajero/EepromFS
.在Arduino IDE中打开库的测试程序示例/测试。此程序将运行EEPROM文件系统的一系列测试。在本教程中,它将被用来解释该库的特性。
在测试程序开始时
#include <EepromFS.h
#include <Wire.h>
EepromFS EFS (0x50, 32768);
将创建一个EepromFS对象。第一个参数是I2C地址,第二个参数是EEPROM的大小。将这些值设置为您的硬件配置。
请上传并运行该测试程序。在输出中,所有的“错误状态”行都应该显示结果0,即,如果EEPROM连接正确,则没有错误。输出的前几行应该是这样的:
-----------------------------------------
文件系统测试
-----------------------------------------
交配32个槽
格式化时间= 171
518字节更新
更新= 24000
错误状态:0
-----------------------------------------
已安装文件系统
4中的32个插槽
错误状态:0
-----------------------------------------
产品的性能和局限性

EepromFS将整个EEPROM空间划分为一个固定长度的等量插槽。在上面的示例中,它创建了32个大约1kB大小的插槽。一个文件可以和插槽的大小一样大,但不能更大。即使在其他插槽中有空间,文件也不能超过一个插槽。这使得文件系统非常简单,因为没有文件分配表或任何其他复杂的目录机制。
文件名可以为12个字符长。同时也可以使用典型的MSDOS 8.3文件名。文件名长度是EepromFS库的一个参数,可以更改为小于28的任何其他值。
只能同时打开两个文件。一个可以打开供读,另一个可以用于写入和附加。
有一个包含16个字节的读/写缓冲区。缓冲区长度可以更改为小于30的任何其他值。
对文件名和缓冲区长度的限制不是来自EepromFS库,而是来自底层的Arduino Wire库。一个I2C事务只能传输32个字节,包括该寻址。这将将有效负载的大小限制为30个字节。EEPROM通常可以处理64或128字节的较大的块大小。要使用这一点,将需要一个具有更大缓冲区大小的有线库。
测试程序可以下载
https://github.com/slviajero/EepromFS/blob/main/examples/baudrate/baudrate.ino
它是如何工作的?

如果您只对库本身及其api感兴趣,则可以跳过此段落。这是关于EEPROM计时和I2C的附加信息。
eeprom是按块组织的。每个方块都可以单独编写。这些块在32到128字节之间。编写一个块是一项耗时的活动,并且需要一个适当的延迟。
EEPROM可以一次接受一个块来进行读取,然后需要时间来消化这些信息。因此,最好在RAM中缓冲数据并一次传输一个块。不幸的是,Arduino I2C库将传输块的大小限制为32个字节。这是由参数设置的
#定义BUFFER_LENGTH 32
在电线线。可以通过编辑该库来更改该参数。这将允许更大的I2C传输尺寸。请注意,twi.h也需要更改,因为参数也出现在那里,并且不会自动调整。
EepromFS库接受标准线和缓冲区16个字节的限制。
库中的读取代码是这样看起来的
eeprom希望该地址在事务开始时以两个字节的形式发送。这发生在第一个代码块中。在第二个代码块中,请求一个缓冲区页(16字节)的数据。一旦库有了可用的数据,它就会被检索到。除了需要在ESP8266系统上使用的延迟(0)外,库中没有延迟,即产生()。读取时间不确定,可用()用于同步EEPROM和Arduino。
写代码处理I2C限制和计时
无符号的intpa=页面编号*EFS_PAGESIZE;
地址传输两个字节,然后Write.write()发送缓冲区。EFS_PAGESIZE默认为16。任何不超过30的尺寸都是可能的,但不能更多。地址和有效负载必须适合于一个32字节的帧中。
传输后,一个快速延迟等待EEPROM消化数据。默认值为10 ms。在这里可以做一些调优。10 ms是一个标准值。有些EEPROM可以做4个ms。我们在这里阻止了库和调用程序,以避免读取与写操作的冲突。
除了此之外,eeprom不需要其他时间延迟。EEPROM的所有其他功能都以I2C总线速度运行。
如果您只需要一个稳定的EEPROM库,并且对文件系统API不感兴趣,那么您可以直接转到RAW API部分。使用这个API,您可以获得定时和缓冲,并可以作为字节数组访问EEPROM。
一个最佳的硬件适应线库将使用64或128字节的完整EEPROM块长度。这将使交易速度加快4到8倍。它还将增加EEPROM的生命周期,因为将避免使用多个缓冲区写入。
请使用POSIX样式的API

POSIX风格的API支持许多标准的C文件IO函数。实现的API函数是
文件句柄是uint8_t,即一个字节整数。
除了这些函数之外,还有一个包含事务错误状态的变量错误。0表示已成功。
将文件写入文件系统的典型程序应该是这样的
有许多例子,包括测试程序中的目录和错误处理
https://github.com/slviajero/EepromFS/blob/main/examples/efstest/efstest.ino
.
大多数函数的行为就像POSIX风格的文件访问函数将工作。
没有字符串打印或扫描功能。字符串转换必须在代码中使用该库来完成。这样,库就保持简单,不包括像String这样需要内存的库。
使用原始API

除了POSIX API之外,该库还提供了一个原始的访问API。这只是利用了读/写缓冲和时间,但不利用文件系统。使用原始API访问EEPROM可以并且将破坏文件系统结构。
我们实现了以下的库函数
EEPROM可以作为一个字节数组来访问。这些函数对应于EEPROM。写()和EEPROM。Arduino IDE的读()函数。所有的访问都是缓冲的,并且避免对I2C总线进行不必要的读写。这个库对于没有内置EEPROM的系统很有用。它为外部EEPROM提供了一个快速和精简的API。
关闭事务需要功能()。如果不需要传输更多的数据,就应该发生这种情况。它可以确保当前的缓冲区被写入到EEPROM中。
这个API的示例程序是
https://github.com/slviajero/EepromFS/blob/main/examples/efstest-eeprom/efstest-eeprom.ino
使用字节API

EepromFS的第三个API类似于原始API,但保护了文件系统结构。
函数获取数据()和输入数据()访问文件系统的一个特定插槽。这个插槽是由一个整数s给出的。如果该插槽已被文件使用,则不进行测试。
这个API的代码片段将是这样的
fopen()语句仅用于创建一个文件,并记住它所在的插槽。调用输入数据()和获取数据()可以访问这个文件,就像标准的Arduino函数EEPROM一样。读取()和EEPROM。写()。必须保护数据。如果没有刷新,代码的读取部分仍然是成功的,因为数据存储在缓冲区中,但它不会被永久地写入EEPROM。
如果读取的数据或写入超出了槽的大小,则忽略事务。fgetc()在槽边界之外返回一个0,fputc()忽略数据。EFS.size()返回插槽中的字节数。
此测试程序可以从
https://github.com/slviajero/EepromFS/blob/main/examples/efstest-byte/efstest-byte.ino
使用基本的EepromFS




用EFS编写的eeprom可以集成并在物联网基本解释器中使用
https://github.com/slviajero/tinybasic
因为EepromFS是该系统中受支持的文件系统之一。你可以从
https://github.com/slviajero/tinybasic/tree/main/IoTBasic
.
使用Arduino UNO,可以编译一个整数基本值。打开IotBasic.ino并设置编译器指令
所有编译器指令都是预期的。
另外,请将EEPROM参数设置为正确的值。
编译并上传草图到Arduino。
由测试程序创建的文件可以与目录一起列出
目录
file1 17
file2 52
测试11
假人
文件可以通过删除和重命名来删除和重命名。
基本的文件访问命令,如打开、关闭、输入和打印,可以用来读取数据。
eeprom可以在运行C++代码的系统和具有图形和物联网功能的更大的基本计算机之间进行交换,就像这些教程中的那样
https://www.instructables.com/A-Arduino-RP2040-Standalone-IoT-Computer-Running-B/
https://www.instructables.com/Build-a-80s-Style-Home-Computer-From-Scratch-From-/
https://www.instructables.com/The-10-Euro-IoT-Computer-With-ESP-8266/
数据可以通过这种方式被打乱,而不需要SD卡文件系统的开销。











