dlt645_2007.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. /*************************************************
  2. Copyright (c) 2019
  3. All rights reserved.
  4. File name: dlt645_2007.c
  5. Description: DLT645 2007版本
  6. History:
  7. 1. Version:
  8. Date: 2019-09-19
  9. Author: wangjunjie
  10. Modify:
  11. *************************************************/
  12. #include "dlt645_private.h"
  13. #include "dlt645_2007_private.h"
  14. #include "string.h"
  15. /**
  16. * Name: dlt645_2007_recv_check
  17. * Brief: DLT645-2007 数据校验
  18. * Input:
  19. * @msg: 校验数据包
  20. * @len: 数据包长度
  21. * @addr: 从站地址
  22. * @code: 操作码
  23. * Output: None
  24. */
  25. int dlt645_2007_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] == 0x94)
  32. return 0;
  33. uint8_t *code_buf = (uint8_t *)&code;
  34. for (uint8_t i = 0; i < 4; i++)
  35. {
  36. code_buf[i] += 0x33;
  37. }
  38. if (*((uint32_t *)(msg + DL645_DATA_POS)) != code)
  39. return -1;
  40. return 0;
  41. }
  42. /**
  43. * Name: dlt645_2007_parsing_data
  44. * Brief: DLT645-2007 数据包解析
  45. * Input:
  46. * @code: 标识符
  47. * @read_data: 数据包指针
  48. * @len: 数据包长度
  49. * @real_val: 数据存储地址
  50. * Output: 数据包长度
  51. */
  52. int dlt645_2007_parsing_data(uint32_t code, uint8_t *read_data, uint16_t len, uint8_t *real_val)
  53. {
  54. switch (code)
  55. {
  56. case DIC_0:
  57. case DIC_100:
  58. case DIC_200:
  59. case DIC_300:
  60. case DIC_400:
  61. case DIC_10000:
  62. case DIC_10100:
  63. case DIC_10001:
  64. case DIC_10002:
  65. case DIC_10200:
  66. case DIC_10300:
  67. case DIC_10400:
  68. case DIC_20000:
  69. case DIC_20100:
  70. case DIC_20200:
  71. case DIC_20300:
  72. case DIC_20400:
  73. case DIC_30000:
  74. case DIC_40000:
  75. case DIC_50000:
  76. case DIC_60000:
  77. case DIC_70000:
  78. case DIC_80000:
  79. case DIC_90000:
  80. {
  81. dlt645_data_parse_by_format_to_float(read_data, 4, "XXXXXX.XX", real_val);
  82. break;
  83. }
  84. // 包含日期信息其原长度为8但其包含五个字节的日期时间长度所以read_data前三个字节为为数据信息,后五个字节为日期时间
  85. case DIC_1010000:
  86. case DIC_1020000:
  87. case DIC_1010001:
  88. case DIC_1020001:
  89. {
  90. dlt645_data_parse_by_format_to_float(read_data, 3, "XX.XXXX", real_val);
  91. // 将剩余的 5 个字节拼接到 real_val 后面
  92. for (int i = 0; i < 5; i++)
  93. {
  94. real_val[4 + i] = read_data[3 + i]-0x33;
  95. }
  96. break;
  97. }
  98. case DIC_201FF00:
  99. case DIC_2010100:
  100. case DIC_2010200:
  101. case DIC_2010300:
  102. case DIC_20C0100:
  103. case DIC_20C0200:
  104. case DIC_20C0300:
  105. {
  106. dlt645_data_parse_by_format_to_float(read_data, 2, "XXX.X", real_val);
  107. break;
  108. }
  109. case DIC_2020100:
  110. case DIC_2020200:
  111. case DIC_2020300:
  112. {
  113. dlt645_data_parse_by_format_to_float(read_data, 3, "XXX.XXX", real_val);
  114. break;
  115. }
  116. case DIC_2030000:
  117. case DIC_2030100:
  118. case DIC_2030200:
  119. case DIC_2030300:
  120. case DIC_2040000:
  121. case DIC_2040100:
  122. case DIC_2040200:
  123. case DIC_2040300:
  124. case DIC_2050000:
  125. case DIC_2050100:
  126. case DIC_2050200:
  127. case DIC_2050300:
  128. {
  129. dlt645_data_parse_by_format_to_float(read_data, 3, "XX.XXXX", real_val);
  130. break;
  131. }
  132. case DIC_2060000:
  133. case DIC_2060100:
  134. case DIC_2060200:
  135. case DIC_2060300:
  136. {
  137. dlt645_data_parse_by_format_to_float(read_data, 2, "X.XXX", real_val);
  138. break;
  139. }
  140. case DIC_2800002:
  141. {
  142. dlt645_data_parse_by_format_to_float(read_data, 2, "XX.XX", real_val);
  143. break;
  144. }
  145. case DIC_5060101:
  146. //case DIC_5040001:
  147. {
  148. for (uint16_t i = 0; i < len; i++)
  149. {
  150. real_val[i] = ((read_data[i] - 0x33) & 0x0f) + ((read_data[i] - 0x33) >> 4) * 10;
  151. }
  152. break;
  153. }
  154. case DIC_4000403:
  155. case DIC_7000001:
  156. case DIC_7000002:
  157. for (uint16_t i = 0; i < len; i++)
  158. {
  159. real_val[i] = read_data[i] - 0x33;
  160. }
  161. break;
  162. default:
  163. for (uint16_t i = 0; i < len; i++)
  164. {
  165. real_val[i] = ((read_data[i] - 0x33) & 0x0f) + ((read_data[i] - 0x33) >> 4) * 10;
  166. }
  167. break;
  168. }
  169. return len;
  170. }
  171. /**
  172. * Name: dlt645_2007_read_data
  173. * Brief: DLT645-2007 数据读取
  174. * Input:
  175. * @ctx: 645句柄
  176. * @addr: 从站地址
  177. * @code: 数据标识
  178. * @read_data: 数据存储地址
  179. * Output: None
  180. */
  181. int dlt645_2007_read_data(dlt645_t *ctx,
  182. uint32_t code,
  183. uint8_t *read_data)
  184. {
  185. uint8_t send_buf[DL645_2007_RD_CMD_LEN];
  186. uint8_t read_buf[DL645_RESP_LEN];
  187. memset(read_buf, 0, sizeof(read_buf));
  188. memset(send_buf, 0, sizeof(send_buf));
  189. memcpy(send_buf + 1, ctx->addr, DL645_ADDR_LEN);
  190. send_buf[DL645_CONTROL_POS] = C_2007_CODE_RD;
  191. send_buf[DL645_LEN_POS] = 4;
  192. uint8_t send_code[4] = {0};
  193. send_code[0] = (code & 0xff) + 0x33;
  194. send_code[1] = ((code >> 8) & 0xff) + 0x33;
  195. send_code[2] = ((code >> 16) & 0xff) + 0x33;
  196. send_code[3] = ((code >> 24) & 0xff) + 0x33;
  197. memcpy(send_buf + DL645_DATA_POS, send_code, 4);
  198. if (dlt645_send_msg(ctx, send_buf, DL645_2007_RD_CMD_LEN) < 0)
  199. {
  200. DLT645_LOG("send data error!\n");
  201. return -1;
  202. }
  203. if (dlt645_receive_msg(ctx, read_buf, DL645_RESP_LEN, code, DLT645_2007) < 0)
  204. {
  205. DLT645_LOG("receive msg error!\n");
  206. return -1;
  207. }
  208. return dlt645_2007_parsing_data(code, read_buf + DL645_DATA_POS + 4, read_buf[DL645_LEN_POS] - 4, read_data);
  209. // #define DL645_DATA_POS 10 //数据位置
  210. }
  211. /**
  212. * Name: dlt645_write_data
  213. * Brief: DLT645-2007 数据写入
  214. * Input:
  215. * @ctx: 645句柄
  216. * @addr: 从站地址
  217. * @code: 数据标识
  218. * @write_data: 写入数据的指针
  219. * @write_len: 写入长度
  220. * Output: None
  221. */
  222. int dlt645_write_data(dlt645_t *ctx,
  223. uint32_t addr,
  224. uint32_t code,
  225. uint8_t *write_data,
  226. uint8_t write_len)
  227. {
  228. uint8_t send_buf[DL645_WR_LEN];
  229. uint8_t read_buf[DL645_RESP_LEN];
  230. memset(read_buf, 0, sizeof(read_buf));
  231. memset(send_buf, 0, sizeof(send_buf));
  232. memcpy(send_buf + 1, ctx->addr, DL645_ADDR_LEN);
  233. send_buf[DL645_CONTROL_POS] = C_2007_CODE_WR;
  234. send_buf[DL645_LEN_POS] = 12 + write_len;
  235. uint8_t send_code[4] = {0};
  236. send_code[0] = (code & 0xff) + 0x33;
  237. send_code[1] = ((code >> 8) & 0xff) + 0x33;
  238. send_code[2] = ((code >> 16) & 0xff) + 0x33;
  239. send_code[3] = ((code >> 24) & 0xff) + 0x33;
  240. for (uint8_t i = 0; i < write_len; i++)
  241. {
  242. write_data[i] += 0x33;
  243. }
  244. memcpy(send_buf + DL645_DATA_POS, send_code, 4);
  245. memcpy(send_buf + DL645_DATA_POS + 12, write_data, write_len);
  246. if (dlt645_send_msg(ctx, send_buf, 24 + write_len) < 0)
  247. {
  248. DLT645_LOG("send data error!\n");
  249. return -1;
  250. }
  251. if (dlt645_receive_msg(ctx, read_buf, DL645_RESP_LEN, code, DLT645_2007) < 0)
  252. {
  253. DLT645_LOG("receive msg error!\n");
  254. return -1;
  255. }
  256. return 0;
  257. }