【问题标题】:How to have the correct representation of words in C+python+UART?如何在 C+python+UART 中正确表示单词?
【发布时间】:2017-04-11 09:44:09
【问题描述】:

在串行通信中,我需要将该密文从 python 发送到能够使用 C 读取的 UART。

首先,在python端使用这个技术:

ciphertext=(b'\x24\x70\xb4\xc5\x5a\xd8\xcd\xb7\x80\x6a\x7b\x00\x30\x69\xc4\xe0\xd8')
ser.write(ciphertext)

在C端,我把接收到的密文放在一个缓冲区中。我测试如果第一个字节24,则数据包的开始:

if (buffer_RX[0]=='\x24')
{
   for (i=1;i<=17;i++) //sizeof(buffer_RX)==17
   {
       printf("%x \n",buffer_RX[i]);
   }
}
else {
   printf("It is not a packet!");
}

我得到的结果是:

70
b4
c5
5a

d8
cd
b7
80

6a
7b
0
30

69
c4
e0
d8

所以我有两个问题, - 拳头是为什么\x00是这样显示的,我的意思是只有一个零0? - 第二个是我怎么会有同样的表现:

const unsigned int ciphertext[4] = {0x70b4c55a, 0xd8cdb780, 0x6a7b0030,0x69c4e0d8};

如果我认为这是字节之间的连接,我的意思是可能:

   unsigned int plaintext[1];
   plaintext[1]= buffer_RX[3]|buffer_RX[4]|buffer_RX[5];

但我不确定,我认为我有语法错误。

此表示将帮助我继续下一步。但我不知道我怎么能得到它。

【问题讨论】:

  • printf("%02x\n",buffer_RX[i]); 将回答您的第一个问题。
  • @wildplasser,它纠正了我的 0,但它发送了另一个 d8 分隔的最后一个字节。 d和8

标签: python c uart


【解决方案1】:

如果你想从你的 1 字节块创建一个 4 字节长的数据。

const unsigned int ciphertext[4] = {0x70b4c55a, 0xd8cdb780, 0x6a7b0030,0x69c4e0d8};

对字节进行 OR 是不够的,您必须将它们移到正确的位置。

您当前正在做什么,(请注意,您已过度索引 plaintext[1] 这应该是 plaintext[0]):

unsigned int plaintext[1];
plaintext[1]= buffer_RX[3]|buffer_RX[4]|buffer_RX[5];

内存中有这个结果,假设int是32位,4字节长:

--------------------------------------------------------------------------------
| 3. byte | 2. byte | 1. byte |                   0. byte                      |
--------------------------------------------------------------------------------
|  0x00   |   0x00  |   0x00  |   buffer_RX[3] | buffer_RX[4] | buffer_RX[5]   |
--------------------------------------------------------------------------------

因此您必须先使用左移运算符&lt;&lt; 将适当的字节移到右侧位置,然后再将字节移到右边。

这是一个例子:

#include <stdio.h>

int main()
{
    unsigned char buffer_RX[4];

    buffer_RX[0] = 0x70;
    buffer_RX[1] = 0xb4;
    buffer_RX[2] = 0xc5;
    buffer_RX[3] = 0x5a;

    unsigned int plaintext[1];

    plaintext[0] = (buffer_RX[0]<<24) | (buffer_RX[1]<<16) | (buffer_RX[2]<<8) | buffer_RX[3];

    printf("plaintext: %08x\n", plaintext[0]);

    return 0;
}

输出:

在内存中:

----------------------------------------------------------------------
|     3. byte     |     2. byte    |     1. byte    |     0. byte    |
----------------------------------------------------------------------
|  buffer_RX[0]   |  buffer_RX[1]  |  buffer_RX[2]  |   buffer_RX[3] |
----------------------------------------------------------------------

您可以看到buffer_RX[0] 已被移动了 24,即 3 个字节,因此它会跳过前三个单元格,跳转到最后一个单元格。

buffer_RX[1] by 16 是 2 个字节,所以它跳到前两个,buffer_RX[2] by 8 这是一个字节,所以它跳过第一个。而buffer_RX[3] 没有移动,因为它排在第一位。


关于0x00,它在 8 位上表示为零。如果您打印它,那将是简单的 0。如果您打印0x0000,它也将是0printf 默认如何打印 0,它不会不必要地打印零。如果您在 32 位变量中有0x70,那么它实际上是0x00000070,但printf 将打印0x70,因为不必要的零被切掉,除非您另有说明。这就是%02x 出现的地方。在%02x 中,02 告诉printf,无论如何你都想显示 2 个字节,所以它会在0x00 的情况下打印两个零

printf("%02x \n",buffer_RX[i]);

如果您想打印0x00000070 的整个 32 位(4 字节),则以下行将执行此操作:

printf("%08x \n",buffer_RX[i]);

【讨论】:

  • 非常感谢您的回答。
猜你喜欢
  • 2017-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-05
  • 1970-01-01
  • 2011-10-18
  • 1970-01-01
相关资源
最近更新 更多