/************************************************* Copyright (c) 2019 All rights reserved. File name: dlt645_2007.c Description: DLT645 2007版本 History: 1. Version: Date: 2019-09-19 Author: wangjunjie Modify: *************************************************/ #include "dlt645_private.h" #include "dlt645_2007_private.h" #include "string.h" /** * Name: dlt645_2007_recv_check * Brief: DLT645-2007 数据校验 * Input: * @msg: 校验数据包 * @len: 数据包长度 * @addr: 从站地址 * @code: 操作码 * Output: None */ int dlt645_2007_recv_check(uint8_t *msg, int len, uint8_t *addr, uint32_t code) { if (dlt645_common_check(msg, len, addr) < 0) { return -1; } if (msg[DL645_CONTROL_POS] == 0x94) return 0; uint8_t *code_buf = (uint8_t *)&code; for (uint8_t i = 0; i < 4; i++) { code_buf[i] += 0x33; } if (*((uint32_t *)(msg + DL645_DATA_POS)) != code) return -1; return 0; } /** * Name: dlt645_2007_parsing_data * Brief: DLT645-2007 数据包解析 * Input: * @code: 标识符 * @read_data: 数据包指针 * @len: 数据包长度 * @real_val: 数据存储地址 * Output: 数据包长度 */ int dlt645_2007_parsing_data(uint32_t code, uint8_t *read_data, uint16_t len, uint8_t *real_val) { switch (code) { case DIC_0: case DIC_100: case DIC_200: case DIC_300: case DIC_400: case DIC_10000: case DIC_10100: case DIC_10001: case DIC_10002: case DIC_10200: case DIC_10300: case DIC_10400: case DIC_20000: case DIC_20100: case DIC_20200: case DIC_20300: case DIC_20400: case DIC_30000: case DIC_40000: case DIC_50000: case DIC_60000: case DIC_70000: case DIC_80000: case DIC_90000: { dlt645_data_parse_by_format_to_float(read_data, 4, "XXXXXX.XX", real_val); break; } // 包含日期信息其原长度为8但其包含五个字节的日期时间长度所以read_data前三个字节为为数据信息,后五个字节为日期时间 case DIC_1010000: case DIC_1020000: case DIC_1010001: case DIC_1020001: { dlt645_data_parse_by_format_to_float(read_data, 3, "XX.XXXX", real_val); // 将剩余的 5 个字节拼接到 real_val 后面 for (int i = 0; i < 5; i++) { real_val[4 + i] = read_data[3 + i]-0x33; } break; } case DIC_201FF00: case DIC_2010100: case DIC_2010200: case DIC_2010300: case DIC_20C0100: case DIC_20C0200: case DIC_20C0300: { dlt645_data_parse_by_format_to_float(read_data, 2, "XXX.X", real_val); break; } case DIC_2020100: case DIC_2020200: case DIC_2020300: { dlt645_data_parse_by_format_to_float(read_data, 3, "XXX.XXX", real_val); break; } case DIC_2030000: case DIC_2030100: case DIC_2030200: case DIC_2030300: case DIC_2040000: case DIC_2040100: case DIC_2040200: case DIC_2040300: case DIC_2050000: case DIC_2050100: case DIC_2050200: case DIC_2050300: { dlt645_data_parse_by_format_to_float(read_data, 3, "XX.XXXX", real_val); break; } case DIC_2060000: case DIC_2060100: case DIC_2060200: case DIC_2060300: { dlt645_data_parse_by_format_to_float(read_data, 2, "X.XXX", real_val); break; } case DIC_2800002: { dlt645_data_parse_by_format_to_float(read_data, 2, "XX.XX", real_val); break; } case DIC_5060101: //case DIC_5040001: { for (uint16_t i = 0; i < len; i++) { real_val[i] = ((read_data[i] - 0x33) & 0x0f) + ((read_data[i] - 0x33) >> 4) * 10; } break; } case DIC_4000403: case DIC_7000001: case DIC_7000002: for (uint16_t i = 0; i < len; i++) { real_val[i] = read_data[i] - 0x33; } break; default: for (uint16_t i = 0; i < len; i++) { real_val[i] = ((read_data[i] - 0x33) & 0x0f) + ((read_data[i] - 0x33) >> 4) * 10; } break; } return len; } /** * Name: dlt645_2007_read_data * Brief: DLT645-2007 数据读取 * Input: * @ctx: 645句柄 * @addr: 从站地址 * @code: 数据标识 * @read_data: 数据存储地址 * Output: None */ int dlt645_2007_read_data(dlt645_t *ctx, uint32_t code, uint8_t *read_data) { uint8_t send_buf[DL645_2007_RD_CMD_LEN]; uint8_t read_buf[DL645_RESP_LEN]; memset(read_buf, 0, sizeof(read_buf)); memset(send_buf, 0, sizeof(send_buf)); memcpy(send_buf + 1, ctx->addr, DL645_ADDR_LEN); send_buf[DL645_CONTROL_POS] = C_2007_CODE_RD; send_buf[DL645_LEN_POS] = 4; uint8_t send_code[4] = {0}; send_code[0] = (code & 0xff) + 0x33; send_code[1] = ((code >> 8) & 0xff) + 0x33; send_code[2] = ((code >> 16) & 0xff) + 0x33; send_code[3] = ((code >> 24) & 0xff) + 0x33; memcpy(send_buf + DL645_DATA_POS, send_code, 4); if (dlt645_send_msg(ctx, send_buf, DL645_2007_RD_CMD_LEN) < 0) { DLT645_LOG("send data error!\n"); return -1; } if (dlt645_receive_msg(ctx, read_buf, DL645_RESP_LEN, code, DLT645_2007) < 0) { DLT645_LOG("receive msg error!\n"); return -1; } return dlt645_2007_parsing_data(code, read_buf + DL645_DATA_POS + 4, read_buf[DL645_LEN_POS] - 4, read_data); // #define DL645_DATA_POS 10 //数据位置 } /** * Name: dlt645_write_data * Brief: DLT645-2007 数据写入 * Input: * @ctx: 645句柄 * @addr: 从站地址 * @code: 数据标识 * @write_data: 写入数据的指针 * @write_len: 写入长度 * Output: None */ int dlt645_write_data(dlt645_t *ctx, uint32_t addr, uint32_t code, uint8_t *write_data, uint8_t write_len) { uint8_t send_buf[DL645_WR_LEN]; uint8_t read_buf[DL645_RESP_LEN]; memset(read_buf, 0, sizeof(read_buf)); memset(send_buf, 0, sizeof(send_buf)); memcpy(send_buf + 1, ctx->addr, DL645_ADDR_LEN); send_buf[DL645_CONTROL_POS] = C_2007_CODE_WR; send_buf[DL645_LEN_POS] = 12 + write_len; uint8_t send_code[4] = {0}; send_code[0] = (code & 0xff) + 0x33; send_code[1] = ((code >> 8) & 0xff) + 0x33; send_code[2] = ((code >> 16) & 0xff) + 0x33; send_code[3] = ((code >> 24) & 0xff) + 0x33; for (uint8_t i = 0; i < write_len; i++) { write_data[i] += 0x33; } memcpy(send_buf + DL645_DATA_POS, send_code, 4); memcpy(send_buf + DL645_DATA_POS + 12, write_data, write_len); if (dlt645_send_msg(ctx, send_buf, 24 + write_len) < 0) { DLT645_LOG("send data error!\n"); return -1; } if (dlt645_receive_msg(ctx, read_buf, DL645_RESP_LEN, code, DLT645_2007) < 0) { DLT645_LOG("receive msg error!\n"); return -1; } return 0; }