DLT645编码解码基本类

C#

基本样例

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DLT645D
{
    class DLT645
    {
        public DLT645()
        {

        }

        enum RTNDATA
        {
            DATA_OK = 0,
            ERR_DATALEN,
            ERR_STARTPOS,
            ERR_CHECKSUM,
            DATA_NULL,//无标识符
        }


        int packet(DataPacketFrame inBuf, ushort len, out byte[] outBuf)
        {
            ushort i = 0;
            ushort pos = 0;
            ushort j = 0;
            byte checkSum = 0;

            outBuf = new byte[256];

            outBuf[i++] = 0xfe;
            outBuf[i++] = 0xfe;
            outBuf[i++] = 0xfe;
            outBuf[i++] = 0xfe;

            pos = i;
            //起始符
            outBuf[i++] = 0x68;
            //地址域
            for (j = 0; j < 6; j++)
            {
                outBuf[i++] = inBuf.addr[j];
            }
            //起始符
            outBuf[i++] = 0x68;
            //控制码
            outBuf[i++] = inBuf.ctr_Code;
            //数据长度
            outBuf[i++] = inBuf.DataLen;
            //数据
            for (j = 0; j < len; j++)
            {
                outBuf[i++] = (byte)(inBuf.Data[j] + 0x33);
            }
            //检验和
            for (j = pos; j < i; j++)
            {

                checkSum += outBuf[j];
            }

            outBuf[i++] = checkSum;

            outBuf[i] = 0x16;

            return 0;
        }


        RTNDATA UnPacket(byte[] inBuf, ushort len, out DataPacketFrame outBuf)
        {

            ushort i = 0;
            ushort pos = 0;
            ushort j = 0;
            byte checkSum = 0;
            outBuf = new DataPacketFrame();
            if (len < 14)
            //if (len < 6)
            {

                return RTNDATA.ERR_DATALEN;
            }
            for (j = 0; j < 4; j++)
            {
                if (inBuf[j] == 0xfe)
                {
                    i++;
                }
            }
            pos = i;

            //前导码
            if (inBuf[i] != 0x68 || inBuf[i + 7] != 0x68)
            {
                return RTNDATA.ERR_STARTPOS;
            }
            i++;

            /*addr*/
            //地址域
            for (j = 0; j < 6; j++)
            {
                outBuf.addr[j] = inBuf[i++];
            }


            i++;
            //控制码
            outBuf.ctr_Code = inBuf[i++];
            //数据长度
            outBuf.DataLen = inBuf[i++];


            //数据
            for (j = 0; j < 4; j++)
            {
                outBuf.DATA_ID[j] = (byte)(inBuf[i++] + 0x33);
            }
            for (j = 0; j < 4; j++)
            {
                outBuf.CIPHER[j] = (byte)(inBuf[i++] + 0x33);
            }

            for (j = 0; j < 4; j++)
            {
                outBuf.operator_Code[j] = (byte)(inBuf[i++] + 0x33);
            }
            for (j = 0; j < len - 12; j++)
            {
                outBuf.Data[j] = (byte)(inBuf[i++] + 0x33);
            }

            //校验和
            for (j = pos; j < i; j++)
            {
                checkSum += (byte)(inBuf[j++] + 0x33);
            }
            outBuf.CheckSum = inBuf[i];

            if(checkSum!=inBuf[i])
            {
                return RTNDATA.ERR_CHECKSUM;
            }else
            {
                outBuf.CheckSum=inBuf[i];
            }

            return RTNDATA.DATA_OK;
        }

        public int testPACKET()
        {

            ushort i = 0;
            ushort len = 0;
            /*FE FE FE FE 68 18 00 00 00 00 00 68 14 10 01 01 00 04 01 00 00 00 78 56 34 12 05 07 08 15 81 16*/
            DataPacketFrame inBuf = new DataPacketFrame();
            byte[] outBuf = new byte[256];

            byte[] addr = { 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 };
            byte[] data = { 0x01, 0x01, 0x00, 0x04, 0x02, 0x00, 0x00, 0x00, 0x78, 0x56, 0x34, 0x12, 0x05, 0x07, 0x08, 0x15 };

            for (i = 0; i < 6; i++)
            {
                inBuf.addr[i] = addr[i];
            }
            inBuf.ctr_Code = 0x14;
            inBuf.DataLen = 0x10;

            len = (ushort)data.Length;

            for (i = 0; i < len; i++)
            {
                inBuf.Data[i] = data[i];
            }

            packet(inBuf, len, out outBuf);

            for (i = 0; i < 32; i++)
            {
                Console.Write(outBuf[i].ToString("X") + " ");
            }
            Console.WriteLine();
            return 0;
        }

        //测试解帧
        public int testUNPACKET()
        {

            DataPacketFrame outBuf;
            byte[] inBuf = { 0xFE, 0xFE, 0xFE, 0xFE, 0x68, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x14, 0x10, 0x01, 0x01, 0x00, 0x04, 0x02, 0x00, 0x00, 0x00, 0x78, 0x56, 0x34, 0x12, 0x05, 0x07, 0x08, 0x15, 0x81, 0x16 };
            //byte[] inBuf = { 0xFE, 0xFE, 0xFE, 0xFE, 0x68, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x68, 0x91, 0x09, 0x33, 0x33, 0x34, 0x33, 0x9A, 0x4C, 0x44, 0x33, 0x36, 0x60, 0x16 };
            ushort i = 0;
            while (inBuf[i] != 0x68)
            {
                i++;
            }
            ushort DataLenPos = (ushort)(i + 9);
            ushort datalen_INT = (ushort)inBuf[DataLenPos];
            UnPacket(inBuf, datalen_INT, out outBuf);

            Console.Write("地址域为:");
            for (int j = 0; j < 6; j++)
            {
                Console.Write(outBuf.addr[j].ToString("X2") + " ");
            }
            Console.WriteLine(Environment.NewLine);
            Console.WriteLine("控制码为:" + outBuf.ctr_Code.ToString("X"));
            Console.WriteLine(Environment.NewLine);

            Console.Write("数据长度为:");
            Console.Write(outBuf.DataLen.ToString("X2") + " ");
            Console.WriteLine(Environment.NewLine);

            Console.Write("数据标识为:");
            for (int j = 0; j < 4; j++)
            {
                Console.Write(outBuf.DATA_ID[j].ToString("X2"));
            }
            Console.WriteLine(Environment.NewLine);
            Console.Write("密码权限为:");
            for (int j = 0; j < 4; j++)
            {
                Console.Write(outBuf.CIPHER[j].ToString("X2"));
            }
            Console.WriteLine(Environment.NewLine);
            Console.Write("操作者代码:");
            for (int j = 0; j < 4; j++)
            {
                Console.Write(outBuf.operator_Code[j].ToString("X2"));
            }
            Console.WriteLine(Environment.NewLine);
            Console.Write("数据:");
            for (int j = 0; j < datalen_INT - 12; j++)
            {
                Console.Write(outBuf.Data[j].ToString("X2"));
            }
            Console.WriteLine(Environment.NewLine);
            Console.Write("数据校验码:");
            Console.Write(outBuf.CheckSum.ToString("X2"));
            Console.WriteLine(Environment.NewLine);

            return 0;
        }

        class DataPacketFrame
        {
            public byte[] addr = new byte[6];
            public byte ctr_Code;
            public byte DataLen;
            public byte[] Data = new byte[256];
            public byte CheckSum;
            public byte[] CIPHER = new byte[4];//密码权限
            public byte[] DATA_ID = new byte[4];//数据标识
            public byte[] operator_Code = new byte[4];
        }
    }
}
 

DLT645协议解析器及modbus CRC和DLT CS校验码计算,支持两种输入格式,带空格和不带空格。默认需要安装微软VS2012发布包。 比如输入FE FE FE FE 68 AA AA AA AA AA AA 68 13 00 DF 16,解析出结果如下: [11-05 08:39:58:676] 输入数据: FE FE FE FE 68 AA AA AA AA AA AA 68 13 00 DF 16 [11-05 08:39:58:681] 型=上1结算日C相反向有功电能 [11-05 08:39:58:685] 型值=76 [11-05 08:39:58:689] 获取结果= 0.00 另外可按键获取如下CRC [11-05 08:39:58:697] *********************************************** [11-05 08:40:08:268] 输入数据:FE FE FE FE 68 AA AA AA AA AA AA 68 13 00 DF 16 [11-05 08:40:08:276] DLT645 CRC=0xCC [11-05 08:40:08:283] *********************************************** [11-05 08:40:10:813] 输入数据:FE FE FE FE 68 AA AA AA AA AA AA 68 13 00 DF 16 [11-05 08:40:10:821] CRC(Modbus)=0x6FE5 [HIGH LOW]=[6F E5] [11-05 09:05:30:239] 输入数据: 68 30 65 00 00 00 00 68 11 04 33 33 33 33 46 16 [11-05 09:05:30:247] 型=当前组合有功总电能 [11-05 09:05:30:254] 型值=1 [11-05 09:05:30:264] 获取结果= 0.00 [11-05 09:06:25:098] 输入数据: 68 29 65 00 00 00 00 68 91 08 35 36 36 33 C9 CC 36 33 C9 16 [11-05 09:06:25:112] 型=上2结算日组合无功1费率3电能 [11-05 09:06:25:127] 型值=11 [11-05 09:06:25:142] 获取结果=399.96 [11-05 09:33:10:453] 输入数据: FE FE FE FE 68 29 65 00 00 00 00 68 11 04 35 35 34 33 44 16 [11-05 09:33:10:460] 型=上2结算日正向有功费率2电能 [11-05 09:33:10:467] 型值=5 [11-05 09:33:10:476] 获取结果= 0.00 [11-05 09:33:10:484] *********************************************** [11-05 09:33:32:065] 输入数据: FEFEFEFE68296500000000681104353534334416 [11-05 09:33:32:074] 型=上2结算日正向有功费率2电能 [11-05 09:33:32:086] 型值=5 [11-05 09:33:32:097] 获取结果= 0.00
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_16215957

如果有帮助一杯咖啡奶茶均可

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值