C++ &引用;按位或;有时工作

C++ &引用;按位或;有时工作,c++,casting,bitwise-operators,C++,Casting,Bitwise Operators,这是我的问题: 我正在用QtCreator编写一个程序,读取一些电池数据(电压、电流等)。每个值以两个字节的形式传递,我必须将它们组合成一个UINT16。 有时,我的程序会正确执行,并显示正确的值(约12V)。 但另一些时候,它不工作,显示约65伏。 只有在将负载连接到电池时,才会出现问题。然后它有时说65V,有时说12V。 我使用了一个旧的程序来观察我从电池中获得的数据,这些数据一直显示在12V左右,所以不是数据出了什么问题 这是我在acutal计划中写的: voltage = data[6]

这是我的问题:

我正在用QtCreator编写一个程序,读取一些电池数据(电压、电流等)。每个值以两个字节的形式传递,我必须将它们组合成一个UINT16。 有时,我的程序会正确执行,并显示正确的值(约12V)。 但另一些时候,它不工作,显示约65伏。 只有在将负载连接到电池时,才会出现问题。然后它有时说65V,有时说12V。 我使用了一个旧的程序来观察我从电池中获得的数据,这些数据一直显示在12V左右,所以不是数据出了什么问题

这是我在acutal计划中写的:

voltage = data[6] << 8;
voltage = voltage | data[7];
voltage = data[6]<<8;
voltage|= data[7]; 
voltage=data[6]以下是我的猜测:
如果数据[7]是有符号字符(显式或由编译器将字符作为有符号值处理),并且比例因子为0.1伏,则从12.7伏变为12.8伏将使数据[7]成为负值。
然后将其符号扩展到16位(通过隐含的强制转换),因此结果值约为65000-等于6500V-类似于您似乎看到的65V(有可能有两个额外的零吗?)。当电压降到12.7V或以下时,即恢复到实际电压

例如:

12.7伏=0b01111111->(符号扩展到16位)->0b00000000 01111111->127->12.7伏

12.8伏=0b10000000->(符号扩展到16位)->0B11111111100000->65408->6540.8伏

这只是一种预感,因为没有提供实际的类型/比例因子

编辑:

你可能想做的是

unsigned int voltage = ((((unsigned int)(data[6])) << 8) | (((unsigned int)data[7])&0xff)) & 0xffff;

unsigned int voltage=(((unsigned int)(data[6])电压/数据和初始化的确切类型以及比例因子(1Volt的值不是多少)都很有用。“old”代码在负载条件下没有此问题?现在了解一下如何初始化
电压
。例如,如果这是
int
而不是
uint
,您可能会遇到这样的问题。65是一个幻数,2^16=65536。请将数据类型更改为无符号类型,以避免si出现问题gn扩展名。换句话说,用无符号字符替换字符。进行一些调试。查找运算符参数的特定值,这些值的行为方式您不理解。不要依赖猜测。@AviPerel旧代码没有这个问题,这让我发疯。它始终显示正确的值,即使我对e电池。“电压”是无符号整数,所以我认为这与此无关。事实上,当我想在旧程序中读取电流时,这是一个问题,因为电流是有符号的。因此,我花了很多时间转换有符号/无符号值,最后我认为我理解了这种转换方法。@Malte是无符号电压整数or类似于uint16_t?数据类型是什么?是字符吗?请提供准确的声明?在.h文件中,“电压”变量声明为uint16。在电池的数据表中,数据类型为无符号int(0-65535)。@Malte数据类型是什么[]在程序中声明?您还可以添加输出(printf或其他)代码吗?同样,当提到“旧”时程序-它是完全相同的程序,只显示了两行更改吗?它是使用相同的编译器为相同的目标编译的吗?它是在相同的目标上运行的吗?我很抱歉一点一点地给你这个信息。我对编程非常陌生,所以我不确定你需要什么。我将在我的第一篇文章中以编辑的形式编写它。
unsigned int voltage = ((((unsigned int)(data[6])) << 8) | (((unsigned int)data[7])&0xff)) & 0xffff;