[关闭]
@Tyhj 2018-12-28T06:04:25.000000Z 字数 2451 阅读 866

串口通信数据格式

Java


最近项目中发现和硬件通信时候出现了一些问题,所以仔细看了一下通信的时候的数据传输,在硬件协议上经常看见要求发送这样格式的数据;这个是十六进制的数据,怎么来构建这种数据来发送呢

  1. 55 AA 01 00 01 00 01

首先和硬件通信,我们一般是通过输入输出流来发送或者接收一个byte[]数组;首先我们得构建这个byte数组

String拼接

简单的命令可以先拼接字符串,再把字符串转成byte数组

  1. String hexStr="55AA0100010001";
  2. //16进制字符串转成byte[]
  3. byte[] bytes=hexStrToByteArray(hexStr);
  4. System.out.println(Arrays.toString(bytes));

打印出来的数据

  1. [85, -86, 1, 0, 1, 0, 1]

十六进制字符串转成byte[]方法

  1. public static byte[] hex2Bytes(final String data) throws Exception {
  2. final int len = data.length();
  3. if ((len & 0x01) != 0) {
  4. throw new Exception("Odd number of characters.");
  5. }
  6. final byte[] out = new byte[len >> 1];
  7. // two characters form the hex value.
  8. for (int i = 0, j = 0; j < len; i++) {
  9. int f = toDigit(data.charAt(j), j) << 4;
  10. j++;
  11. f = f | toDigit(data.charAt(j), j);
  12. j++;
  13. out[i] = (byte) (f & 0xFF);
  14. }
  15. return out;
  16. }

byte数组拼接

其实这个和字符串拼接是差不多的,byte[]的拼接方法

  1. //java 合并两个byte[]
  2. public static byte[] byteMerger(byte[] byte1, byte[] byte2){
  3. byte[] byte3 = new byte[byte1.length+byte2.length];
  4. System.arraycopy(byte1, 0, byte3, 0, byte1.length);
  5. System.arraycopy(byte2, 0, byte3, byte1.length, byte2.length);
  6. return byte3;
  7. }
  8. //合并多个byte[]
  9. private static byte[] byteMergerAll(byte[]... values) {
  10. int length_byte = 0;
  11. for (int i = 0; i < values.length; i++) {
  12. length_byte += values[i].length;
  13. }
  14. byte[] all_byte = new byte[length_byte];
  15. int countLength = 0;
  16. for (int i = 0; i < values.length; i++) {
  17. byte[] b = values[i];
  18. System.arraycopy(b, 0, all_byte, countLength, b.length);
  19. countLength += b.length;
  20. }
  21. return all_byte;
  22. }

有一个问题,就是每个byte应该是十进制的,刚才十六进制字符串转成byte[]的方法,可以看到转后的byte数组是[85, -86, 1, 0, 1, 0, 1]55十进制就是85AA十进制就是170,一个byte为8位二进制,最大表示的数字是2^8 = 256,byte的取值范围是-128~127-86就表示170可以简单理解为:256-170=86

所以比如AA需要转成170,再转为byte,(byte)170;或者直接写成byte(0xAA)也是可以的

  1. public static final byte HEAD = 0xAA;

比如现在有个问题,55 AA 01 00 00 00 01,如果我中间三个00是用三位来表示一个数值的,这个时候用byte来拼接;首先十进制转十六进制

  1. String hexStr = Integer.toHexString(100);

然后字符串再转成byte[],但是在转之前要保证hexStr长度为2的倍数,不足要先在前面加一个0;
其实没有必要,byte[]保存的就是十进制,直接int转byte[]就好了

  1. /**
  2. * int整数转换为4字节的byte数组
  3. *
  4. * @param i
  5. * 整数
  6. * @return byte数组
  7. */
  8. public static byte[] intToByte4(int i) {
  9. byte[] targets = new byte[4];
  10. targets[3] = (byte) (i & 0xFF);
  11. targets[2] = (byte) (i >> 8 & 0xFF);
  12. targets[1] = (byte) (i >> 16 & 0xFF);
  13. targets[0] = (byte) (i >> 24 & 0xFF);
  14. return targets;
  15. }
  16. /**
  17. * long整数转换为8字节的byte数组
  18. *
  19. * @param lo
  20. * long整数
  21. * @return byte数组
  22. */
  23. public static byte[] longToByte8(long lo) {
  24. byte[] targets = new byte[8];
  25. for (int i = 0; i < 8; i++) {
  26. int offset = (targets.length - 1 - i) * 8;
  27. targets[i] = (byte) ((lo >>> offset) & 0xFF);
  28. }
  29. return targets;
  30. }
  31. /**
  32. * short整数转换为2字节的byte数组
  33. *
  34. * @param s
  35. * short整数
  36. * @return byte数组
  37. */
  38. public static byte[] unsignedShortToByte2(int s) {
  39. byte[] targets = new byte[2];
  40. targets[0] = (byte) (s >> 8 & 0xFF);
  41. targets[1] = (byte) (s & 0xFF);
  42. return targets;
  43. }

推荐阅读:Android串口通信工具

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注