我正在尝试使用标准的Arduino EEPROM-Library Routine EEPROM.put()将4个结构中的所有值保存到我的ATMega328P EEPROM中,并通过EEPROM.get()检索它们。如何将value_table中的所有值传递给这些函数?这是我的数据的样子。
typedef struct EXAMPLE {
uint8_t part1[7][2];
uint8_t part2[3];
} *ptr[5];
EXAMPLE VALUE_1 = {{
{1, 8},
{2, 9},
{3, 10},
{4, 11},
{5, 12},
{6, 13},
{7, 14}
},
{15, 16, 17}
};
在指针数组中有四个版本VALUE_1到VALUE_4。
struct EXAMPLE *value_table[] = {&VALUE_1, &VALUE_2, &VALUE_3, &VALUE_4};
这是我提出的,但会产生错误的结果。
EEPROM.put(0, &value_table); // 0 is first byte of EEPROM
EEPROM.get(0, value_table);
我想要存储的是位于VALUE_1 - VALUE_4中的值,以使其持久化。
我非常感谢每一个提示!
答案 0 :(得分:0)
猜猜:
// writing (starting at some "eeprom_address" address)
int eeprom_address = 0;
EEPROM.put(eeprom_address + 0*sizeof(EXAMPLE), VALUE_1);
EEPROM.put(eeprom_address + 1*sizeof(EXAMPLE), VALUE_2);
EEPROM.put(eeprom_address + 2*sizeof(EXAMPLE), VALUE_3);
EEPROM.put(eeprom_address + 3*sizeof(EXAMPLE), VALUE_4);
// reading
EEPROM.get(eeprom_address + 0*sizeof(EXAMPLE), VALUE_1);
EEPROM.get(eeprom_address + 1*sizeof(EXAMPLE), VALUE_2);
EEPROM.get(eeprom_address + 2*sizeof(EXAMPLE), VALUE_3);
EEPROM.get(eeprom_address + 3*sizeof(EXAMPLE), VALUE_4);
// plus set the value_table in the same way as before
struct EXAMPLE *value_table[] = {&VALUE_1, &VALUE_2, &VALUE_3, &VALUE_4};
没有必要将指针存储到EEPROM中,您应该只存储数据值(但是以结构化的方式存储,因此您知道哪个字节属于哪个数据项,并且可以将它们正确地读取到目标变量中)。
如果您想使用单一结构,请执行struct EXAMPLE value_table[] = {VALUE_1, VALUE_2, VALUE_3, VALUE_4};
。但是这会将VALUE_1复制到value_table中,因此它的内存只会是单个VALUE_1的两倍。
int
地址仅用作官方文档的副本,我个人绝对不会使用int
作为地址,突然之间我计划在遥远的未来点检查Arduino得到更多遥远。
使用for
变体写作:
constexpr size_t VALUES_N = 4;
struct EXAMPLE *value_table[] = {&VALUE_1, &VALUE_2, &VALUE_3, &VALUE_4};
// writing (starting at some "eeprom_address" address)
int eeprom_address = 0;
for (size_t i = 0; i < VALUES_N; ++i) {
EEPROM.put(eeprom_address + i*sizeof(EXAMPLE), *(value_table[i]));
}
// reading
for (size_t i = 0; i < VALUES_N; ++i) {
EEPROM.get(eeprom_address + i*sizeof(EXAMPLE), *(value_table[i]));
}
答案 1 :(得分:0)
下载了Arduino并查看了get
和put
。正如所料,他们已经模仿
template< typename T > T &get( int idx, T &t )
template< typename T > const T &put( int idx, const T &t )
因为它们引用了模板定义类型的参数,所以它们知道大小以及在EEPROM上执行读或写操作所需的其他所有内容。
希望线下put
的某个位置在写入失败时抛出异常,因为我没有看到任何throw
或其他错误通知方法,但这不是问题所在。
因此...
struct EXAMPLE *value_table[] = {&VALUE_1, &VALUE_2, &VALUE_3, &VALUE_4};
是一个由4个指针组成的数组,而不是结构本身。这意味着
sizeof(value_table);
将是指针大小的四倍,可能是Arduino上的16个字节。但
EEPROM.put(0, &value_table);
甚至没有写出来。因为它传入一个指向value_table
的指针,所有将要编写的指针都是一个指针,由于数组的工作方式,它将是指向第一个条目的指针,这是一个指向要存储的数据的指针。
get
和put
通过引用获取数据,因此无需明确地使用指针。不幸的是,因为模板几乎可以采用任何编译器警告或错误来捕获这个错误。
要put
,您有两种选择:
EEPROM.put(0, VALUE_1 );
EEPROM.put(sizeof(VALUE_1), VALUE_2);
EEPROM.put(sizeof(VALUE_1)*2, VALUE_3);
...
EEPROM.put(sizeof(VALUE_1)*(N-1), VALUE_N);
或执行相同操作的循环,或者用EXAMPLE结构的表替换EXAMPLE结构的指针表。
struct EXAMPLE value_table[] =
{
{
{
{1, 8},
{2, 9},
{3, 10},
{4, 11},
{5, 12},
{6, 13},
{7, 14}
},
{15, 16, 17}
},
{
// contents of VALUE_2
},
{
// contents of VALUE_3
},
...
{
// contents of VALUE_N
}
}
VALUE_1
等......被丢弃了。
而是使用value_table[x]
,其中x
是值编号-1或定义
enum VALUES
{
VALUE_1 = 0,
VALUE_2,
VALUE_3,
...
VALUE_N
}
并以value_table[VALUE_1]
的形式访问该表格。这种方法有点冗长,但更容易阅读。
对put
的调用仍然与目前使用的内容类似,只是失去了运营商的地址。
EEPROM.put(0, value_table);
使用get
非常相似
EEPROM.get(0, VALUE_1 );
EEPROM.get(sizeof(VALUE_1), VALUE_2);
EEPROM.get(sizeof(VALUE_1)*2, VALUE_3);
...
EEPROM.get(sizeof(VALUE_1)*(N-1), VALUE_N);
或
EEPROM.get(0, value_table);
取决于选择处理put
的方法。