dlt645_1997.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /*************************************************
  2. Copyright (c) 2019
  3. All rights reserved.
  4. File name: dlt645_1997.c
  5. Description: DLT645 1997版本
  6. History:
  7. 1. Version:
  8. Date: 2019-09-19
  9. Author: wangjunjie
  10. Modify:
  11. *************************************************/
  12. #include "dlt645_private.h"
  13. #include "dlt645_1997_private.h"
  14. #include "string.h"
  15. /**
  16. * Name: dlt645_1997_recv_check
  17. * Brief: DLT645-1997 数据校验
  18. * Input:
  19. * @msg: 校验数据包
  20. * @len: 数据包长度
  21. * @addr: 从站地址
  22. * @code: 操作码
  23. * Output: 校验成功:0 ,失败 -1
  24. */
  25. int dlt645_1997_recv_check(uint8_t *msg, int len, uint8_t* addr, uint32_t code)
  26. {
  27. if (dlt645_common_check(msg, len, addr) < 0)
  28. {
  29. return -1;
  30. }
  31. if (msg[DL645_CONTROL_POS] == 0x84)
  32. return 0;
  33. uint8_t *code_buf = (uint8_t *)&code;
  34. for (uint8_t i = 0; i < 2; i++)
  35. {
  36. code_buf[i] += 0x33;
  37. }
  38. if (*((uint16_t *)(msg + DL645_DATA_POS)) != code)
  39. return -1;
  40. return 0;
  41. }
  42. /**
  43. * Name: dlt645_1997_parsing_data
  44. * Brief: DLT645-1997 数据包解析
  45. * Input:
  46. * @code: 标识符
  47. * @read_data: 数据包指针
  48. * @len: 数据包长度
  49. * @real_val: 数据存储地址
  50. * Output: 数据包长度
  51. */
  52. static int dlt645_1997_parsing_data(uint32_t code, uint8_t *read_data, uint16_t len, uint8_t *real_val)
  53. {
  54. switch (code)
  55. {
  56. case DIC_B611:
  57. case DIC_B612:
  58. case DIC_B613:
  59. case DIC_B691:
  60. case DIC_B692:
  61. case DIC_B693:
  62. {
  63. dlt645_data_parse_by_format_to_float(read_data, 2, "XXX", real_val);
  64. break;
  65. }
  66. case DIC_B621:
  67. case DIC_B622:
  68. case DIC_B623:
  69. {
  70. dlt645_data_parse_by_format_to_float(read_data, 2, "XX.XX", real_val);
  71. break;
  72. }
  73. case DIC_B630:
  74. case DIC_B631:
  75. case DIC_B632:
  76. case DIC_B633:
  77. {
  78. dlt645_data_parse_by_format_to_float(read_data, 3, "XX.XXXX", real_val);
  79. break;
  80. }
  81. default:
  82. {
  83. for (uint16_t i = 0; i < len; i++)
  84. {
  85. real_val[i] = ((read_data[i] - 0x33) & 0x0f) + ((read_data[i] - 0x33) >> 4) * 10;
  86. }
  87. break;
  88. }
  89. }
  90. return len;
  91. }
  92. /**
  93. * Name: dlt645_1997_read_data
  94. * Brief: DLT645-1997 数据读取
  95. * Input:
  96. * @ctx: 645句柄
  97. * @addr: 从站地址
  98. * @code: 数据标识
  99. * @read_data: 数据存储地址
  100. * Output: 成功返回数据长度,失败返回-1
  101. */
  102. int dlt645_1997_read_data(dlt645_t *ctx,
  103. uint32_t code,
  104. uint8_t *read_data)
  105. {
  106. uint8_t send_buf[DL645_1997_RD_CMD_LEN];
  107. uint8_t read_buf[DL645_RESP_LEN];
  108. memset(read_buf, 0, sizeof(read_buf));
  109. memset(send_buf, 0, sizeof(send_buf));
  110. memcpy(send_buf + 1, ctx->addr, DL645_ADDR_LEN);
  111. send_buf[DL645_CONTROL_POS] = C_1997_CODE_RD;
  112. send_buf[DL645_LEN_POS] = 2;
  113. uint8_t send_code[2] = {0};
  114. send_code[0] = (code & 0xff) + 0x33;
  115. send_code[1] = ((code >> 8) & 0xff) + 0x33;
  116. memcpy(send_buf + DL645_DATA_POS, send_code, 2);
  117. if (dlt645_send_msg(ctx, send_buf, DL645_1997_RD_CMD_LEN) < 0)
  118. {
  119. DLT645_LOG("send data error!\n");
  120. return -1;
  121. }
  122. if (dlt645_receive_msg(ctx, read_buf, DL645_RESP_LEN, code, DLT645_1997) < 0)
  123. {
  124. DLT645_LOG("receive msg error!\n");
  125. return -1;
  126. }
  127. return dlt645_1997_parsing_data(code, read_buf + DL645_DATA_POS + 2, read_buf[DL645_LEN_POS] - 2, read_data);
  128. }