arduino - ATTINY84:反转字节顺序的奇怪问题
问题描述
我将 6 个值(4x 3bit + 1bit)编码为 16bit 整数,并通过串行将它们传输到 ATTINY84,将它们分成 2 个字节。这一切都很好,直到我将字节重新组合成一个 16 位整数。
例子:
我正在发送以下二进制状态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
时,它全部关闭。
任何帮助,将不胜感激。
解决方案
所以看起来我掉进了小/大端的陷阱。
基本上正如阿兰所说,在评论中 - 一切都是正确的,这只是陈述。
我想出了以下方法,可以从需要采用大端格式的小端存储数字中提取位:
/**
* @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
希望对某人有所帮助。
推荐阅读
- windows - 如何使用隐藏运行的 Inno Setup 添加计划任务
- python - 是否可以在 cython 定义的类的实例上使用 __dict__ 属性?
- javascript - 渲染
- java - 如何将 Thrift 导入 Java 程序?
- javascript - 无法在未登录的情况下重定向到重置密码链接
- nullpointerexception - 删除 Janusgraph 顶点时出现 Nullpointerexception
- python - Odoo 12:我无法使用域过滤树视图
- java - ProcessBuilder 无法识别 gcc 命令
- nuxt.js - 新的 mapboxgl.NavigationControl() 不起作用
- heroku - Heroku 无法加载 ./.env