2016-08-04 28 views
0

对于某些项目,我必须将有符号整数从Java over serial发送到微控制器上的C++程序。它对于正整数很好地工作,但负整数被包裹起来并在C++端显示为正整数。通过串行发送负整数

下面是发送在Java端的INT功能:

void writeIntToSerial(Serial port, int number) { 
    port.write(byte(number << 24)); 
    port.write(byte(number << 16)); 
    port.write(byte(number << 8)); 
    port.write(byte(number << 0)); 
} 

我不只是之前和之后的有效载荷发送原始整数,但一些控制字符。所有这一切正常。

接收(C++)端将输入流读入char的缓冲区数组,然后根据流中的控制字符用状态机解释流。

的字符流转换回整数部分是一个基本的位位移:

int startAngle = 0; 
// [...] 
startAngle = (payload[0] << 24) + (payload[1] << 16) + (payload[2] << 8) + payload[3]; 

如前所述,它工作得很好,为正值,但即-60将转换为196(256 - 60 )。

我意识到解决方案可能是微不足道的,但我一直在盯着这段代码太久......我迷路了。

+1

这是你的实际的代码?我很难相信即使对于正值,显示的代码也能工作。 – Kayaman

+0

是的。当发布这个我意识到粘贴写**浮动** ToSerial(),而不是写在Java端的Java ** ToSerial(),但那是从那以后更正。代码工作正常(对于正整数)。 – Oldaric

+1

那么'port.write()'的定义是什么?显然它需要一个int参数,但它对它有什么作用?由于您正在向左移动,因此在尝试发送int'-1'时,它首先会写入'0xFF000000',然后'0xFFFF0000',然后'0xFFFFFF00',最后写入'0xFFFFFFFF'。我无法想象'write()'只会使用8个最重要的位。 – Kayaman

回答

0

它看起来就像你序列化的一端是float,另一端是int。由于这些数据类型在内部存储的方式必然存在一些不一致之处。

因此,无论您发送/接收浮动INT,但不要混合起来

+0

是的,我刚刚意识到我粘贴了错误的功能。现在在OP中查看实际的writeIntToSerial()。 Sry对此 – Oldaric

0

这是因为你将它们加在一起,所以它们会被标记为32位。

如果你或他们在一起,你应该得到正确的结果。

+0

我刚刚将接收端更改为此 startAngle =(payload [0] << 24)| (有效载荷[1] << 16)| (有效载荷[2] << 8)|有效载荷[3]; 具有相同的结果。这是你的意思吗? – Oldaric

0

在您的例子,当您发送-60您发送的字节

0000 0000 
0000 0000 
0000 0000 
1100 0100 

,然后你重新给

0...1100 0100 

是196,所以代码工作得很好。如果你发送了一个大于255的正数,你也应该在接收端伪造。这是因为您正在向Java方向错误地移动

+0

沟通的一方是小端,另一端是大端。这就是为什么我以接收方字节顺序发送字节。这可能是一个愚蠢的后续问题,但如果你说的是对的,我不会得到60,当我发送60,对吗? – Oldaric

+0

你真的应该看看'htonl'和'ntohl'函数 - 在你的μC程序中使用它们,并且总是在你的java应用程序中转换成/从网络字节顺序 - 这将确保你的协议不依赖于OS/μC依赖 – specializt

+0

如果将java int向左移位8位或更多位,然后将其转换为字节,则总是会得到0.所以是的,当您翻转移位时,在发送60后应该接收60。对于60(这是<256),应该是没有变化的情况 – RafToTheK

0

我猜那个有效载荷的类型是char或unsigned char? 然后有效载荷[x] < < y会移入无符号字符大小,显然不会超过8位。如果我的假设是真的,你的代码应该是

startAngle = (static_cast<unsigned int>payload[0]) << 24) + ((static_cast<unsigned int>payload[1]) << 16) + ((static_cast<unsigned int>payload[2]) << 8) + payload[3]; 
+0

你的推理很有意义,但不幸的是结果是相同的(60 - > 60,-60 - > 196) – Oldaric

+0

sry,static_cast ( - 60)对负数不正确。尝试使用unsigned int来代替。相应地编辑我的回答 –

+0

可悲的是,没有改变。我必须稍微更换一些括号以使其顺便工作。我的转换大气压是这样的: (的static_cast (有效载荷[0])<< 24) +(的static_cast (有效载荷[1])<< 16) +(的static_cast (有效载荷[2])<< 8 ) +有效载荷[3]; – Oldaric

0

好吧。

在发送端我需要右移代替左移:

void writeIntToSerial(Serial port, int number) { 
    port.write((number >> 24)); 
    port.write((number >> 16)); 
    port.write((number >> 8)); 
    port.write(number); 
} 

而在接收端该位位移铸序列的伎俩:

startAngle = (static_cast<uint32_t>(payload[0]) << 24) 
      | (static_cast<uint32_t>(payload[1]) << 16) 
      | (static_cast<uint32_t>(payload[2]) << 8) 
      | payload[3];