如何将大整数转换为字节
How to convert a large integer to bytes
我需要通过串行通信将值 115200
作为参数发送到外部设备,该设备需要将参数作为字节数组的一部分,格式为:0x00, 0x00, 0x00, 0x00
并且我有不知道如何将其转换成那种格式。
我在 Processing 中这样做,所以 Processing/java 解决方案对未来很方便,但是 ATM 我很高兴我可以用这个特定变量发送消息。
这是字节数组:
byte[] tx_cmd = { 0x55, -86, // packet header (-86 == 0xAA)
0x01, 0x00, // device ID
0x00, 0x00, 0x00, 0x00, // input parameter NEEDS TO BE 115200
0x04, 0x00, // command code
0x00, 0x01 }; // checksum
参数需要放在第5到第8个位置(byte[4] - byte[7])。
消息格式为小端 这是消息结构:
0 0x55 BYTE 命令起始代码 1
1 0xAA BYTE 命令起始代码 2
2 设备 ID WORD 设备 ID:默认为 0x0001,始终固定
4 参数 DWORD 输入参数
8 命令字命令代码
10 校验和 WORD
校验和(字节加法)
OFFSET[0]+…+OFFSET[9]=校验和
如有任何建议,我们将不胜感激。
谢谢
你需要屏蔽和移动
int num = 115200
int b1 = (num & 0xff000000) >> 24
int b2 = (num & 0x00ff0000) >> 16
int b3 = (num & 0x0000ff00) >> 8
int b4 = (num & 0x000000ff) >> 0
你尝试将一个int打包成字节,你没有提到它是否是网络顺序,所以我们假设它是(例如第一个字节,tx_cmd[4],是数字的最高字节):
unsigned int baudrate = 115200;
tx_cmd[4] = (baudrate >> 24) & 0xff;
tx_cmd[5] = (baudrate >> 16) & 0xff;
tx_cmd[6] = (baudrate >> 8) & 0xff;
tx_cmd[7] = baudrate & 0xff;
一般来说,拥有像 int_to_bytes
和类似的函数是非常方便的,它们以通用的方式执行此操作并使代码不那么混乱。
对于预期为小端格式的字节,您可以按如下方式设置它们:
uint32_t value = 115200;
tx_cmd[4] = value & 0xff;
tx_cmd[5] = (value >> 8) & 0xff;
tx_cmd[6] = (value >> 16) & 0xff;
tx_cmd[7] = (value >> 24) & 0xff;
您使用的值是无符号的,这一点很重要,否则如果设置了最高有效位,您就有可能移入 1。
建议创建一个函数来打包所有东西
#define byte_n(x, b) ((x >> (b*8)) & 0xFF)
void CreatePacket(byte tx_cmd[], uint16_t device_id, uint32_t param, uint16_t command) {
#define HEADER 0xAA55
tx_cmd[0] = byte_n(HEADER, 0);
tx_cmd[1] = byte_n(HEADER, 1);
tx_cmd[2] = byte_n(device_id, 0);
tx_cmd[3] = byte_n(device_id, 1);
tx_cmd[4] = byte_n(param, 0);
tx_cmd[5] = byte_n(param, 1);
tx_cmd[6] = byte_n(param, 2);
tx_cmd[7] = byte_n(param, 3);
tx_cmd[8] = byte_n(command, 0);
tx_cmd[9] = byte_n(command, 1);
unsigned checksum = 0;
for (int i=0; i<10; i++) {
checksum += tx_cmd[i];
}
tx_cmd[10] = byte_n(checksum, 0);
tx_cmd[11] = byte_n(checksum, 1);
}
byte tx_cmd[12];
device_id = 1;
baud = 115200;
command = 4;
CreatePacket(tx_cmd, device_id, baud, command);
我需要通过串行通信将值 115200
作为参数发送到外部设备,该设备需要将参数作为字节数组的一部分,格式为:0x00, 0x00, 0x00, 0x00
并且我有不知道如何将其转换成那种格式。
我在 Processing 中这样做,所以 Processing/java 解决方案对未来很方便,但是 ATM 我很高兴我可以用这个特定变量发送消息。
这是字节数组:
byte[] tx_cmd = { 0x55, -86, // packet header (-86 == 0xAA)
0x01, 0x00, // device ID
0x00, 0x00, 0x00, 0x00, // input parameter NEEDS TO BE 115200
0x04, 0x00, // command code
0x00, 0x01 }; // checksum
参数需要放在第5到第8个位置(byte[4] - byte[7])。
消息格式为小端 这是消息结构:
0 0x55 BYTE 命令起始代码 1
1 0xAA BYTE 命令起始代码 2
2 设备 ID WORD 设备 ID:默认为 0x0001,始终固定
4 参数 DWORD 输入参数
8 命令字命令代码
10 校验和 WORD 校验和(字节加法) OFFSET[0]+…+OFFSET[9]=校验和
如有任何建议,我们将不胜感激。 谢谢
你需要屏蔽和移动
int num = 115200
int b1 = (num & 0xff000000) >> 24
int b2 = (num & 0x00ff0000) >> 16
int b3 = (num & 0x0000ff00) >> 8
int b4 = (num & 0x000000ff) >> 0
你尝试将一个int打包成字节,你没有提到它是否是网络顺序,所以我们假设它是(例如第一个字节,tx_cmd[4],是数字的最高字节):
unsigned int baudrate = 115200;
tx_cmd[4] = (baudrate >> 24) & 0xff;
tx_cmd[5] = (baudrate >> 16) & 0xff;
tx_cmd[6] = (baudrate >> 8) & 0xff;
tx_cmd[7] = baudrate & 0xff;
一般来说,拥有像 int_to_bytes
和类似的函数是非常方便的,它们以通用的方式执行此操作并使代码不那么混乱。
对于预期为小端格式的字节,您可以按如下方式设置它们:
uint32_t value = 115200;
tx_cmd[4] = value & 0xff;
tx_cmd[5] = (value >> 8) & 0xff;
tx_cmd[6] = (value >> 16) & 0xff;
tx_cmd[7] = (value >> 24) & 0xff;
您使用的值是无符号的,这一点很重要,否则如果设置了最高有效位,您就有可能移入 1。
建议创建一个函数来打包所有东西
#define byte_n(x, b) ((x >> (b*8)) & 0xFF)
void CreatePacket(byte tx_cmd[], uint16_t device_id, uint32_t param, uint16_t command) {
#define HEADER 0xAA55
tx_cmd[0] = byte_n(HEADER, 0);
tx_cmd[1] = byte_n(HEADER, 1);
tx_cmd[2] = byte_n(device_id, 0);
tx_cmd[3] = byte_n(device_id, 1);
tx_cmd[4] = byte_n(param, 0);
tx_cmd[5] = byte_n(param, 1);
tx_cmd[6] = byte_n(param, 2);
tx_cmd[7] = byte_n(param, 3);
tx_cmd[8] = byte_n(command, 0);
tx_cmd[9] = byte_n(command, 1);
unsigned checksum = 0;
for (int i=0; i<10; i++) {
checksum += tx_cmd[i];
}
tx_cmd[10] = byte_n(checksum, 0);
tx_cmd[11] = byte_n(checksum, 1);
}
byte tx_cmd[12];
device_id = 1;
baud = 115200;
command = 4;
CreatePacket(tx_cmd, device_id, baud, command);