“按位或”有时会起作用

时间:2013-10-08 09:47:59

标签: c++ casting bitwise-operators

这是我的问题:

我正在QtCreator中编写一个程序,它读出一些电池数据(电压,电流......)。每个值以两个字节传递,我必须将它们组合成UINT16。 有时我的程序正确并显示正确的值(大约12V)。 但其他时间它不起作用并显示约65V。 仅当我已将负载连接到电池时才会出现此问题。然后它有时说65V,有时说12V。 我使用较旧的程序来观察从电池获得的数据,这些数据一直表示大约12V,因此不是数据错误

这是我在我的实际计划中所写的:

voltage = data[6] << 8;
voltage = voltage | data[7];

到目前为止我发现了什么:

如果电压达到特定值(例如从12.X V降至11.X V),则不会出现问题,似乎没有系统。

我已经将我得到的值转换为二进制数,以查看是否有任何交换。事实并非如此。

旧程序执行此操作,与我的实际程序中的相同:

voltage = data[6]<<8;
voltage|= data[7]; 

编辑: - 这就是我对交付数据的了解:

格式:无符号整数

单位:mV

范围:0到65,535 mV ==&gt; 1000 = 1V

  • 对于'电压​​'变量,我在新程序中选择了UINT16。
  • 在我的旧代码中,我使用无符号短路来表示“电压”。当我在新程序中更改此项时,这对我的问题没有影响。

有关该计划如何运作的更多信息可能会有所帮助:

  • 读出缓冲区(14个字节)
  • 检查第一个字节是否为'$'(相关数据的徽章)
  • 检查第二个字节是否为7(电池数据标志)
  • 然后执行移位和按位或我上面写的内容
  • 打印结果

最奇怪的是,它有时会在施加负载时起作用,如果我等待一段时间它不再起作用,那么突然它再次起作用等等,无论电压是多少。

EDIT2:

节目不同,除了我的段落外,一切都有所不同。我只是在阅读这段电池数据/我建造这个区域。旧程序是使用MSVisual Studio 2009 C ++ Express编写的。 对于新程序,我使用QtCreator和Mingw4.8作为编译器。 data []的类型为QByteArray:

在.h: UINT16电压;

在.c:

QByteArray data = com_port.readLine(1000);

if (data[0] == '$')
            {
                switch (data[1])
                {
                    case 7:
                       voltage  = data[6]<<8;
                       voltage  = voltage|data[7];
                       qDebug() << voltage;
                }
             }

两个程序的目标是相同的,我使用相同的电池。

1 个答案:

答案 0 :(得分:6)

这是我的猜测: 如果您的数据[7]是带符号的char(显式或由编译器将char作为有符号值处理),并且如果比例因子为0.1伏,那么从12.7伏到12.8伏将使数据[7]成为负值。 然后你签名将它扩展到16位(通过隐含的强制转换),因此你的结果值大约为65000 - 大约等于6500V - 类似于你看到的65V(任何可能有几个额外的零? )。你下降到12.7V或更低的那一刻 - 你又回到了真正的电压。

例如:

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

12.8伏特= 0b10000000 - &gt; (符号扩展到16位) - &gt; 0b11111111 10000000 - &gt; 65408 - &gt; 6540.8伏

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

编辑:

您可能想要做的是

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

您可以将unsigned int更改为UINT16。您可能会丢失一些括号(基于运算符优先级)并删除最后一个“&amp; 0xffff”,但这是明确的。