我正在将6个值(4x 3位+ 1位)编码为16位整数,并通过串行方式将它们传输到ATTINY84,将它们分成2个字节。一切正常,直到我将字节重新组装为16bit整数为止。
示例:
我正在发送以下二进制状态0001110000001100
,它转换为7180
并被拆分为[18, 28]
的字节数组。
我正在将该字节数组放入EEPROM中,并在下一个上电周期读取它。
重启后,我的串行调试输出如下:
18
28
7180
太棒了。看起来不错,我在那部分的代码是:
byte d0 = EEPROM.read(0);
byte d1 = EEPROM.read(1);
unsigned int w = d0 + (256 * d1);
但是现在最奇怪的事情发生了。当我逐点阅读时,我会回来:
0011000000111000
should be:
0001110000001100
通过:
for(byte t = 0; t < 16; t++) {
serial.print(bitRead(w, t) ? "1" : "0");
}
位表示完全相反。那怎么可能?或者,也许我缺少了一些东西。
我还确认,当我提取实际的3位位置以接收我的原始值0..7
时,一切都关闭了。
任何帮助将不胜感激。
答案 0 :(得分:0)
所以看起来我掉入了小/大尾数陷阱。
基本上如Alain所说,在评论中-一切正确,只是表象。
我想出了以下方法,该方法可以从需要大端格式的小端存储数字中提取位:
/**
* @bex
*/
uint8_t bexd(uint16_t n, uint8_t o, uint8_t l, uint8_t d) {
uint8_t v = 0;
uint8_t ob = d - o;
for (uint8_t b=ob; b > (ob-l); b--) v = ( v << 1 ) | ( 0x0001 & ( n >> (b-1) ) );
return v;
}
uint8_t bexw(uint16_t n, uint8_t o, uint8_t l) {return bexd(n, o, l, 16);}
uint8_t bexb(uint8_t n, uint8_t o, uint8_t l) {return bexd(n, o, l, 8);}
例如:
在大字节序中,“第二”值存储在位3,4和5中,而在小字节序中,“第二”值存储在位10、11和12中。上述方法允许工作“小字节序”。 “值,就像它将是一个“大端”值。
要从该值0011000000111000
中提取第二个值,只需执行以下操作:
byte v = bex(7180, 3, 3); // 111
Serial.println(v); // prints 255
希望能帮助某人。