Ken*_*ent 23 c++ struct arduino
我有一个结构:
typedef struct {
uint8_t month; // 1..12 [4 bits]
uint8_t date; // 1..31 [5 bits]
uint8_t hour; // 00..23 [5 bits]
uint8_t minute; // 00..59 [6 bits]
uint8_t second; // 00..59 [6 bits]
} TimeStamp;
Run Code Online (Sandbox Code Playgroud)
但我想打包它所以它只消耗4个字节而不是5个字节.
有没有办法改变位以创建更严格的结构?
它可能看起来不多,但是它会进入EEPROM,因此在4Kb页面中保存1个字节是额外的512个字节(我可以使用剩下的6个额外的其他东西).
Ian*_*ing 29
您正在寻找的是位域.
它们看起来像这样:
typedef struct {
uint32_t month : 4; // 1..12 [4 bits]
uint32_t date : 5; // 1..31 [5 bits]
uint32_t hour : 5; // 00..23 [5 bits]
uint32_t minute : 6; // 00..59 [6 bits]
uint32_t second : 6; // 00..59 [6 bits]
} TimeStamp;
Run Code Online (Sandbox Code Playgroud)
根据您的编译器,为了在没有填充的情况下适合4个字节,uint32_t在这种情况下,成员的大小必须是4个字节(即).否则结构成员将填充到每个字节边界不溢出,如果使用,则产生5字节的结构uint8_t.将此作为一般规则应有助于防止编译器差异.
这是一个MSDN链接,深入到位域:
Cub*_*bic 14
一般来说,Bitfields是一种"正确"的方式,但为什么不从年初开始存储秒数呢?4个字节足以舒适地存储这些; 实际上,4个字节足以存储1970年到2038年之间的秒数.只要您知道当前年份(您可以将其与其他信息一起存储),从中获取其他信息就是一个简单的练习.作为您感兴趣的覆盖时间不到70年的时间范围(即便如此,您可以将时间戳分组为68年范围并为每个范围存储偏移量).
Ser*_*sen 12
另一种解决方案是将值存储在一个32位变量中,并使用位移检索各个项目.
uint32_t timestamp = xxxx;
uint8_t month = timestamp & 0x0F;
uint8_t date = (timestamp & 0x1F0) >> 4;
uint8_t hour = (timestamp & 0x3E00) >> 9;
uint8_t minute = (timestamp & 0xFC000) >> 14;
uint8_t second = (timestamp & 0x3F00000) >> 20;
Run Code Online (Sandbox Code Playgroud)