C 从EEPROM读取,并知道其在启动时未写入

C 从EEPROM读取,并知道其在启动时未写入,c,embedded,C,Embedded,我将一个结构写入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 t

我将一个结构写入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;
我通过一个软件设置数据,该软件会写入该结构

问题是,当第一次读取该结构而不写入时,我读取了错误的数据

我需要检测那个点。我如何知道读取的数据是否为假,或者我如何知道我在没有软件的情况下读取了数据。

您可以在结构的末尾添加一个or,它是对结构的所有成员计算的

将数据写入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;
CRC=(AmpF您可以在结构的末尾添加一个or,它是在结构的所有成员上计算的

当您将数据写入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;

CRC=(AmpF一种方法是在eeprom中增加一个字节
检查eeprom
。这是在读取结构之前读取的。第一次,您可以将0x55写入此字节。如果您将此字节读取为0x55,则eeprom设置为有效值,否则您需要初始化它。此检查可以在初始化例程中完成

// read check_eeprom from eeprom
if (check_eeprom == 0x55)
{
   // Normal operation
}
else
{
   // First time. Write default values

   // write 0x55 into check_eeprom location
}

一种方法是在eeprom中增加一个字节
检查\u eeprom
。这是在读取结构之前读取的。第一次,您可以将0x55写入此字节。如果您将此字节读取为0x55,则eeprom设置为有效值,否则您需要对其进行初始化。此检查可以在初始化例程中完成

// read check_eeprom from eeprom
if (check_eeprom == 0x55)
{
   // Normal operation
}
else
{
   // First time. Write default values

   // write 0x55 into check_eeprom location
}

简易方法是在首次读取时设置一个标志,以帮助确定是否为首次读取


在执行读取操作时,检查是否设置了标志。如果设置了标志,则执行通常的读取和处理。如果未设置标志,则表示它是第一次读取,因此用默认值填充结构。确保在第一次读取操作结束时设置标志。

设置是最简单的方法第一次读取时的一种标志,用于帮助确定是否是第一次读取


在执行读取操作时,检查是否设置了标志。如果设置了标志,则执行通常的读取和处理。如果未设置标志,则表示这是第一次读取,因此用默认值填充结构。确保在第一次读取操作结束时设置了标志。

如果校验和错误,则m用户应该用软件写结构吗?如果你计算的校验和不匹配你读的校验和,就意味着你不能认为你所读的数据是有效的。这可能是因为你以前没有写过它,或者因为它被破坏了。你可以在错误管理中处理它。但是要知道它的局限性。对于校验和,如果你有能力做CRC,那可能值得做!我从来没有听说过校验和被称为CRC。@奥拉夫我希望我能说同样的话,但我几乎每天都要面对它。也许是区域性的,或者只是我的公司,谁知道呢。@TimF:哦,另一种方式是很常见的。但是校验和的CRC对于谁来说不是一个好的参考如果校验和是错误的,那意味着用户应该用软件写这个结构吗?如果你计算的校验和不匹配你读的校验和,就意味着你不能认为你读的数据是有效的。这可能是因为你以前没有写过它,或者因为它被破坏了。错误管理。但是要注意校验和的局限性,如果你有能力做CRC,那么可能值得做!我从来没有听说过校验和被称为CRC。@奥拉夫我希望我能说同样的话,但我几乎每天都要面对它。可能是区域性的,或者只是我的公司,谁知道呢。@TimF:哦,另一种方式是很常见的。但是校验和的t CRC对于任何使用它的人来说都不是一个很好的参考。