我有一个非常奇怪的不一致 我准备读取Arduino上的二进制文件(对于midi播放器,如果你感兴趣的话)。 如果我尝试将Arduino上的4个字节组合成一个long,它会给我一个错误的结果 但是,如果我在PC上使用等效代码,我会得到正确的值。
输入为:0x12481248(0x12,0x48,0x12,0x48)(实际上是一个随机数)。
Arduino给出:4680。
Code :: Blocks给出:306713160。
4680与0x1248相同,是在Arduino上使用int而不是long时得到的结果(省略2个字节)。
Arduino代码:
void setup(){
Serial.begin(57600);
char read1 = 0x12;
char read2 = 0x48;
char read3 = 0x12;
char read4 = 0x48;
unsigned long testint = read1<<24|read2<<16|read3<<8|read4;
unsigned long testint2 = 306713160;
Serial.println(testint);
Serial.println(testint2);
}
void loop(){}
testint2表明它不是由Serial.println()引起的。串行监视器输出确实是:
4680
306713160
C ++代码:
#include <iostream>
using namespace std;
int main(){
char read1 = 0x12;
char read2 = 0x48;
char read3 = 0x12;
char read4 = 0x48;
unsigned long testint = read1<<24|read2<<16|read3<<8|read4;
cout << testint;
}
知道发生了什么事吗?
另外,有没有人知道用Arduino / SD库转换字节的更好/更漂亮的方式?
答案 0 :(得分:8)
在Arduino上,int
尺寸is 16 bits。
在这一行:
unsigned long testint = read1<<24|read2<<16|read3<<8|read4;
即使结果存储在unsigned long
(32位)中,按位操作也会在int
s上完成。
将此行更改为:
unsigned long testint = (unsigned long)read1 << 24
| (unsigned long)read2 << 16
| (unsigned long)read3 << 8
| (unsigned long)read4;
答案 1 :(得分:4)
我希望在sizeof(int)= 2的任何平台上得到结果4680(= 0x1248),我认为这是arduino的情况。
那是因为(read1&lt;&lt; 24)被隐式转换为int(不长),所以上面的两个字节丢失了。 Yout应该将read *转换为unsigned long first
答案 2 :(得分:0)
您还可以使用以下代码:
uint8_t data[4];
data[0]=read4;
data[1]=read3;
data[2]=read2;
data[3]=read1;
unsigned long testint =*(unsigned long*)(&data);