重要提示:我不想使用库来实现此目的。没有“avr/io.h”,也没有“avr/eeprom.h”。我想学习如何实现这样的库。
问题:假设我想向 UNO 的 EEPROM 写入一个字节。从数据表中我看到以下内容
可用EEPROM:1Kbytes(1024字节)
这是引用的描述
EEPROM 地址寄存器 – EEARH 和 EEARL 指定 256/512/512/1K 字节 EEPROM 空间中的 EEPROM 地址。 EEPROM 数据字节在 0 和 255/511/511/1023 之间线性寻址。 EEAR 的初始值未定义。在访问 EEPROM 之前必须写入正确的值。 EEAR8 是 ATmega328P 中未使用的位,必须始终写入零。
我的困惑从这里开始。根据寄存器描述,EEARH 位 1-7 被保留,位 0 必须始终为 0。这使得我们只能使用 EEARL(8 位寄存器)来寻址所有 1024 个字节。这是不可能的,因为我们只有 [0, 256) 个可用的唯一值。所以我继续阅读并发现数据表中包含此内容。
这表明 EEPROM 被分为多个页,每个页有 4 个字节。这对我来说很有意义 (1024/4) = 256。完美,我可以用 EEARL 单独寻址每一页。
这就是我继续困惑的地方。假设我想在 EEPROM 中写入第二个字节一些值。然而,我们刚刚得出结论,要覆盖 EEPROM 的整个地址空间,我们必须只对页进行寻址。那么我该如何写第二个字节呢?
我觉得我对这里发生的事情有一些根本性的误解?我将继续思考这可能如何运作,也许这将有助于揭开上述误解。
想法 1:我可以将第一页地址 (0x00) 加载到 EEARL 中并执行写入。但这会写入我假设的页面中的第一个字节吗?如果我不关心第一个字节,那么我可以将 2 字节字写入 EEPROM。破坏第一个字节但成功写入第二个字节。然而,EEPROM 数据寄存器(要写入的值)是 8 位。因此,我一次只能写一个字节,那么我怎么能写一个2字节的值。
想法 2:我可以将第一页地址 (0x00) 加载到 EEARL 中并执行写入。如果我继续保持 EEARL 不变并写入后续字节,则正在写入的字节可能会自动递增,并且我已成功写入第二个字节?
预先感谢您提供的任何帮助!