2

这是我的问题:

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

这是我在我的实际程序中写的:

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

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

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

我已经将我得到的值转换为二进制数,看看是否有任何交换。不是这种情况。

旧程序这样做,在我的实际程序中是一样的:

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

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

格式:无符号整数

单位:毫伏

范围:0 至 65,535 mV ==> 1000 = 1V

  • 对于“电压”变量,我在新程序中选择了 UINT16。
  • 在我的旧代码中,我使用“电压”的无符号缩写。当我在我的新程序中更改它时,这对我的问题没有影响。

有关该程序如何工作的更多信息,可能会有所帮助:

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

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

编辑2:

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

In .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;
                }
             }

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

4

1 回答 1

6

这是我的猜测:如果您的数据 [7] 是有符号字符(显式或由您的编译器将 char 处理为有符号值),并且如果比例因子为 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 位)-> 0b11111111 10000000 -> 65408 -> 6540.8 伏

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

编辑:

你可能想要做的是

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

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

于 2013-10-08T10:17:57.323 回答