我需要在EEPROM中存储8个继电器的状态。我不想为移动而烦恼,我喜欢使用位字段。所以我想这样定义它们:
typedef struct{
uint8_t RELAY0_STATE:1;
uint8_t RELAY1_STATE:1;
uint8_t RELAY2_STATE:1;
uint8_t RELAY3_STATE:1;
uint8_t RELAY4_STATE:1;
uint8_t RELAY5_STATE:1;
uint8_t RELAY6_STATE:1;
uint8_t RELAY7_STATE:1;
}relay_nvm_t;
relay_nvm_t relay_nvm;在我的主要代码流中,我使用relay_nvm变量设置每个中继的状态。示例
...
if(something)
{
relay_nvm.RELAY0_STATE = 1;
relay_nvm.RELAY1_STATE = 0;
relay_nvm.RELAY2_STATE = 1;
relay_nvm.RELAY3_STATE = 0;
relay_nvm.RELAY4_STATE = 1;
relay_nvm.RELAY5_STATE = 1;
relay_nvm.RELAY6_STATE = 0;
relay_nvm.RELAY7_STATE = 1;
}最后,当我需要对EEPROM进行读写时,我只是将relay_nvm转换为uint8_t,以便将一个字节读/写到EEPROM。但我得到了error: conversion to non-scalar type requested错误。以下是我的职责。
static void NVM_Relay_Read(void)
{
relay_nvm = (relay_nvm_t)NVM_ReadEepromByte(NVM_RELAY_INDEX);
}
static void NVM_Relay_Write(relay_nvm_t rs)
{
NVM_WriteEepromByte(NVM_RELAY_INDEX, (uint8_t)rs);
}我们有办法克服这个错误吗?我以为我可以用打字机来做。位字段的使用使我的工作非常容易,代码更容易理解。
我知道在这种情况下,由于填充的原因,位字段可能不安全,但我认为我可以使用POP-PUSH (它值得吗?)
发布于 2020-06-15 07:42:18
我看到了更多的方法来处理这件事:
uint8_t relay_nvm;
#define RELAY0_MASK 1
#define RELAY1_MASK 2
#define RELAY2_MASK 4
...
#define RELAY7_MASK 128
// set exact relays state:
relay_nvm = RELAY0_MASK | RELAY2_MASK | RELAY4_MASK | ... ;
// set single relay (others left unchanged):
relay_nvm |= RELAY2_MASK;
// clear single relay (others left unchanged):
relay_nvm &= ~RELAY2_MASK;
// check current state of a relay:
if (relay_nvm & RELAY2_MASK) { ... }发布于 2020-06-15 09:30:31
,我不想麻烦移动,我喜欢使用位字段。
如果使用按位运算符是一个“麻烦”,那么你可能不应该写嵌入式系统代码,直到你掌握了它们的窍门.对于编写非标准的、不可移植的代码来说,这是一个非常糟糕的理由。
与按位版本不同的是,位字段存在大量问题:未定义的位顺序、无依赖项、未指定的符号性、对齐和填充打嗝等等。您已经在用uint8_t位字段编写特定于平台的代码,因为C标准没有涵盖这些代码。
如果坚持使用位字段,则必须阅读特定的编译器文档,说明它们是如何实现的。不要假设有任何关于如何分配事物的保证,因为在这种情况下没有标准化。
您的具体问题是,您不能直接从结构类型(简单地说是“容器类型”)转换为uint8_t和back,原因与不能使用数组进行转换的原因相同。您必须使用指向第一个元素的指针,然后将其转换为uint8_t*和去引用。但这也伴随着一系列与对齐、兼容类型和“严格混叠”相关的问题。
结构和联合在一般情况下并不适合用于内存映射,尤其是在可移植性方面。至少,您必须启用#pragma pack(1)或类似的编译器特定命令的打包。
因此,您应该考虑完全删除位字段,并在原始uint8_t上使用位运算符,因为这样可以解决太多的问题。
顺便提一下,存储在EEPROM中的所有变量都必须是volatile限定的,所有指向它们的指针也必须是限定的。否则,当您启用优化时,程序很有可能会失控。
https://stackoverflow.com/questions/62383368
复制相似问题