我将结构写入EEPRM,如下所示
typedef struct
{
fract32 AmpF; // amplitude fundamental
fract32 AmpH; // amplitude harmonic
UINT32 b;
UINT16 d;
UINT16 crc;
}CoilBoardAmp_T;
// mechanic angles and salt water angles of coil stored in coil-eeprom
typedef struct
{
ChannelData_T channel[NUM_CHANNELS];
CoilBoard_T coilboard;
CoilBoardAmp_T coil_h;
CoilBoardAmp_T coil_d;
// UINT32 gCoilSerialNumber;
// UINT32 gInversSerialNumber;
} Coil_Eeprom_Data_T;
我通过软件设置数据,该软件写入该结构。
问题是在第一次读取该结构时没有写入它,我读取了错误的数据。
我需要发现这一点。我怎么知道如果读取的数据是错误的,或者我怎么知道我在没有软件的情况下读取数据。
答案 0 :(得分:4)
您可以在结构的末尾添加checksum或CRC,这是在所有结构成员上计算的。
当您将数据写入EEPROM时,您将计算校验和的值并进行写入。当您从EEPROM读取数据时,您将计算此数据的校验和,并将其与您刚刚读取的数据的校验和进行比较,如果匹配,则表示您的数据正确(很有可能)。
基本上,如果我们在内存中表示你的结构:
byte |0 1 2 3|4 5 6 7|8 9 10 11|12 13|14 15|
AmpF AmpH b d CRC
然后可以像这样计算2字节的CRC:
CRC = (AmpF<<2) + (AmpF & 0x00FF)
+ (AmpH<<2) + (AmpH & 0x00FF)
+ (h<<2) + (h & 0x00FF)
+ d;
显然可以使用for
循环进行优化。我很确定'Net上有一些例子,但是想法是从你的结构地址到这个地址+ sizeof(struct) - sizeof(CRC),步长为2个字节。
Internet充满了校验和和CRC的实现,从非常简单到非常复杂,取决于您想要实现的目标和系统功能,但基本上简单的校验和只是添加了数据结构中的所有字节。
像我给出的那样一个简单的校验和只检测数据中的错误位,你不会检测是否交换了两个值,例如AmpF和AmpH。
请注意,尽管校验和和CRC是不同的,但这两个术语通常用于指定另一个。
答案 1 :(得分:1)
这样做的一种方法是在EEPROM中增加一个字节check_eeprom
。在阅读结构之前阅读。第一次,您可以将0x55写入此字节。如果将此字节读为0x55,则EEPROM设置为有效值,否则需要初始化它。这个检查可以在init例程中完成
// read check_eeprom from eeprom
if (check_eeprom == 0x55)
{
// Normal operation
}
else
{
// First time. Write default values
// write 0x55 into check_eeprom location
}
答案 2 :(得分:0)
简单的方法是在第一次读取时设置FLAG,以帮助确定是否首次读取。
执行读取操作时,请检查是否设置了FLAG。如果设置了FLAG,则执行常规读取和处理。如果未设置FLAG,则表示它是第一次读取,因此使用默认值填充结构。确保在第一次读取操作结束时设置FLAG。