123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Runtime.InteropServices;
- using System.Text;
- using System.Threading.Tasks;
- namespace MECF.Framework.RT.Core.IoProviders.Mitsubishis
- {
- public class MelsecMCBin
- {
- public MelsecMCBin()
- {
- m_nNetNo = 0x00;//本站
- m_nPLCNo = 0xFF;
- m_nIONo = 0xFF03;
- m_nStationNo = 0x00;
- m_nTimeOut = 0x1000;
- m_bytelist = new List<byte>();
- m_nDataLen = 12;//不包括软元件数据
- }
- /// <summary>
- /// 检查起始地址和读取长度
- /// </summary>
- /// <returns></returns>
- private bool check()
- {
- if (m_nElementDataLen < 0 || m_nElementDataLen > m_melsecElement.m_nLen)
- {
- return false;
- }
- if (m_nElementStartAddr < m_melsecElement.m_nStartAddr || m_nElementStartAddr > m_melsecElement.m_nEndAddr)
- {
- return false;
- }
- return true;
- }
- /*************读协议内容******************************
- * 副标题(2)50 00|网络编号(1)00|PLC编号(1)FF
- * IO编号(2)FF 03|站编号(1)00|请求数据长度(2)_12
- * 应答超时(2)1000|命令(2)_|子命令(2)_|起始地址(3)_
- * 请求软元件代码(1)|请求点数长度(2)
- * ***************************************************/
- /// <summary>
- /// 构建读取字节
- /// </summary>
- public byte[] getReadBytes()
- {
- m_bytelist.Clear();
- if (check())
- {
- m_enumSubTitle = EnumsubTitle.Request;
- m_bytelist.AddRange(StringHelper.ConverterToBytes(m_enumSubTitle, 2));
- m_bytelist.AddRange(StringHelper.ConverterToBytes(m_nNetNo, 1));
- m_bytelist.AddRange(StringHelper.ConverterToBytes(m_nPLCNo, 1));
- m_bytelist.AddRange(StringHelper.ConverterToBytes(m_nIONo, 2));
- m_bytelist.AddRange(StringHelper.ConverterToBytes(m_nStationNo, 1));
- m_bytelist.AddRange(StringHelper.ConverterToBytes(m_nDataLen, 2, false));
- m_bytelist.AddRange(StringHelper.ConverterToBytes(m_nTimeOut, 2));
- m_bytelist.AddRange(StringHelper.ConverterToBytes(m_enumCmd, 2, false));
- m_bytelist.AddRange(StringHelper.ConverterToBytes(m_enumSubCmd, 2, false));
- m_bytelist.AddRange(StringHelper.ConverterToBytes(m_nElementStartAddr, 3, false));
- m_bytelist.AddRange(StringHelper.ConverterToBytes(m_melsecElement.m_nBinCode, 1));
- m_bytelist.AddRange(StringHelper.ConverterToBytes(m_nElementDataLen, 2, false));
- }
- return m_bytelist.ToArray();
- }
- /****************写协议内容**********************************
- * 副标题(2)50 00|网络编号(1)00|PLC编号(1)FF
- * IO编号(2)FF 03|站编号(1)00|请求数据长度(2)_12+写入数据长度
- * 应答超时(2)1000|命令(2)_|子命令(2)_|起始地址(3)_
- * 请求软元件代码(1)|请求点数长度(2)|写入数据(分按位和按字)
- * ***********************************************************/
- /// <summary>
- /// 构建写字节
- /// </summary>
- /// <param name="nLen">写入数据长度</param>
- public byte[] getWriteBytes(int nLen)
- {
- m_bytelist.Clear();
- if (check())
- {
- m_enumSubTitle = EnumsubTitle.Request;
- m_bytelist.AddRange(StringHelper.ConverterToBytes(m_enumSubTitle, 2));
- m_bytelist.AddRange(StringHelper.ConverterToBytes(m_nNetNo, 1));
- m_bytelist.AddRange(StringHelper.ConverterToBytes(m_nPLCNo, 1));
- m_bytelist.AddRange(StringHelper.ConverterToBytes(m_nIONo, 2));
- m_bytelist.AddRange(StringHelper.ConverterToBytes(m_nStationNo, 1));
- m_nDataLen += nLen;
- m_bytelist.AddRange(StringHelper.ConverterToBytes(m_nDataLen, 2, false));
- m_bytelist.AddRange(StringHelper.ConverterToBytes(m_nTimeOut, 2));
- m_bytelist.AddRange(StringHelper.ConverterToBytes(m_enumCmd, 2, false));
- m_bytelist.AddRange(StringHelper.ConverterToBytes(m_enumSubCmd, 2, false));
- m_bytelist.AddRange(StringHelper.ConverterToBytes(m_nElementStartAddr, 3, false));
- m_bytelist.AddRange(StringHelper.ConverterToBytes(m_melsecElement.m_nBinCode, 1));
- m_bytelist.AddRange(StringHelper.ConverterToBytes(m_nElementDataLen, 2, false));
- m_bytelist.AddRange(StringHelper.ConverterToBytes(m_nElementData, nLen));
- }
- return m_bytelist.ToArray();
- }
- //MelsecMCBinSend: 500000FFFF03000E001000011400000000009D0100000F 按字写
- //MelsecMCBinRece: D00000FFFF030002000000
- /****************读应答正常协议内容**********************************
- * 副标题(2)D0 00|网络编号(1)00|PLC编号(1)FF
- * IO编号(2)FF 03|站编号(1)00|应答数据长度(2)_
- * 结束代码(2)00 00|应答数据部分
- * ***********************************************************/
- public byte[] getReadRespond(byte[] byteRespond)
- {
- if (byteRespond.Length > 11)
- {
- int nLen = StringHelper.ConverterToInt(byteRespond[7], byteRespond[8]) - 2;
- if (nLen == byteRespond.Length - 11)
- {
- for (int n = 0; n < nLen; n++)
- {
- byteRespond[n] = byteRespond[byteRespond.Length - n - 1];
- }
- Array.Resize(ref byteRespond, nLen);
- }
- return byteRespond;
- }
- return null;
- }
- /****************写应答正常协议内容**********************************
- * 副标题(2)D0 00|网络编号(1)00|PLC编号(1)FF
- * IO编号(2)FF 03|站编号(1)00|应答数据长度(2)02 00
- * 结束代码(2)00 00
- * D0 00 |00 |FF |FF 03| 00| 02 00 |00 00
- * ***********************************************************/
- public bool getWriteRespond(byte[] byteRespond)
- {
- string strRespond = StringHelper.GetHexString(byteRespond, byteRespond.Length);
- string strTemp = "D00000FFFF030002000000";
- return string.Equals(strTemp, strRespond);
- }
- /****************应答异常协议内容**********************************
- * 副标题(2)D0 00|网络编号(1)00|PLC编号(1)FF
- * IO编号(2)FF 03|站编号(1)00|应答数据长度(2) 0B 00
- * 结束代码(2)51 C0
- *
- * 网络编号(1)00|PLC编号(1)FF
- * IO编号(2)FF 03|站编号(1)00|命令(2)|子命令(2)
- * ***********************************************************/
- public int getRespondCode(byte[] byteRespond)
- {
- if (byteRespond.Length > 10)
- {
- return StringHelper.ConverterToInt(byteRespond[9], byteRespond[10]);
- }
- return -1;
- }
- /*副标题*/
- public EnumsubTitle m_enumSubTitle { get; set; }
- /*网络编号*/
- public int m_nNetNo { get; set; }
- /*PLC编号*/
- public int m_nPLCNo { get; set; }
- /*IO编号*/
- public int m_nIONo { get; set; }
- /*站编号*/
- public int m_nStationNo { get; set; }
- /*数据长度*/
- public int m_nDataLen { get; set; }
- /*CPU监视定时器,命令输出到接收应答文件时间*/
- public int m_nTimeOut { get; set; }
- /*命令*/
- public EnumCmd m_enumCmd { get; set; }
- /*子命令*/
- public EnumSubCmd m_enumSubCmd { get; set; }
- /*软元件*/
- public MelsecElement m_melsecElement { get; set; }
- /*起始软元件地址*/
- public int m_nElementStartAddr { get; set; }
- /*软元件数据长度*/
- public int m_nElementDataLen { get; set; }
- /*软元件数据*/
- public int m_nElementData { get; set; }
- /*结束代码*/
- public EnumEndCode m_nEndCode { get; set; }
- /*临时存放字节数组*/
- private List<byte> m_bytelist;
- public enum EnumsubTitle
- {
- Request = 0x5000,//请求
- Respond = 0xD000,//应答
- }
- public enum EnumEndCode
- {
- Ok = 0x0000,//正常应答
- Err = 0x51C0,//异常应答
- }
- public enum EnumCmd
- {
- ReadBatch = 0x0401,//成批读
- WriteBatch = 0x1401,//成批写
- }
- /// <summary>
- /// 返回byte数组
- /// </summary>
- public enum EnumSubCmd
- {
- /*有存储扩展模块b7=0,b6=0:随机读出,监视数据注册用外*/
- Bit = 0x0001,//按位读写
- Word = 0x0000,//按字读写
- /*有存储扩展模块b7=1,b6=0:随机读出,监视数据注册用外*/
- BitEx = 0x0081,//按位读写
- WordEx = 0x0080,//按字读写
- }
- }
- public static class StringHelper
- {
- public static byte[] ConverterToBytes(object value, int length,bool reverse=true)
- {
- byte[] src = new byte[length];
- for (int i = 0; i < length; i++)
- {
- src[i] = (byte)(((byte)value >> (i*8)) & 0xFF);
- }
- return src;
- }
- public static int ConverterToInt(byte value1, byte value2)
- {
- int result = value1 << 8 + value2;
- return result;
- }
- public static string GetHexString(byte[] byteRespond, int length)
- {
- StringBuilder result = new StringBuilder();
- foreach (byte bytes in byteRespond)
- {
- result.AppendFormat("{0:x2}", bytes);
- }
- return result.ToString();
- }
- }
- }
|