三菱mc协议服务器客户端,三菱MC协议部分实现

没有经过测试的代码

1、软原件类型

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

namespace TechSysWCS.Model

{

class MelsecElement

{

public static MelsecElement relaySpecial =

new MelsecElement("特殊继电器", "SM", 0x91, 0x000000, 0x002047, MelsecElement.EnumType.Bit);

public static MelsecElement storageSpecial =

new MelsecElement("特殊寄存器", "SD", 0xA9, 0x000000, 0x002047, MelsecElement.EnumType.Word, 960);

public static MelsecElement relayInput =

new MelsecElement("输入继电器", "X*", 0x9C, 0x000000, 0x001FFF, MelsecElement.EnumType.Bit);

public static MelsecElement relayOutPut =

new MelsecElement("输出继电器", "Y*", 0x9D, 0x000000, 0x001FFF, MelsecElement.EnumType.Bit, 7168);

public static MelsecElement relayInner =

new MelsecElement("内部继电器", "M*", 0x90, 0x000000, 0x008191, MelsecElement.EnumType.Bit, 7904);

public static MelsecElement relayLock =

new MelsecElement("锁存继电器", "L*", 0x92, 0x000000, 0x008191, MelsecElement.EnumType.Bit);

public static MelsecElement relayAlarm =

new MelsecElement("报警继电器", "F*", 0x93, 0x000000, 0x002047, MelsecElement.EnumType.Bit);

public static MelsecElement relayEdge =

new MelsecElement("边沿继电器", "V*", 0x94, 0x000000, 0x002047, MelsecElement.EnumType.Bit);

public static MelsecElement relayLink =

new MelsecElement("链接继电器", "B*", 0xA0, 0x000000, 0x001FFF, MelsecElement.EnumType.Bit);

public static MelsecElement storageData =

new MelsecElement("数据寄存器", "D*", 0xA8, 0x000000, 0x012287, MelsecElement.EnumType.Word, 960);

public static MelsecElement storageLink =

new MelsecElement("链接寄存器", "W*", 0xB4, 0x000000, 0x001FFFF, MelsecElement.EnumType.Word, 960);

public static MelsecElement relayTS =

new MelsecElement("定时器触点", "TS", 0xC1, 0x000000, 0x002047, MelsecElement.EnumType.Bit);

public static MelsecElement relayTC =

new MelsecElement("定时器线圈", "TN", 0xC0, 0x000000, 0x002047, MelsecElement.EnumType.Bit);

public static MelsecElement storageTN =

new MelsecElement("定时器当前值", "TC", 0xC2, 0x000000, 0x002047, MelsecElement.EnumType.Word, 960);

public static MelsecElement relaySS =

new MelsecElement("累计定时器触点", "SS", 0xC7, 0x000000, 0x002047, MelsecElement.EnumType.Bit);

public static MelsecElement relaySC =

new MelsecElement("累计定时器线圈", "SC", 0xC6, 0x000000, 0x002047, MelsecElement.EnumType.Bit);

public static MelsecElement storageSN =

new MelsecElement("累计定时器当前值", "SN", 0xC8, 0x000000, 0x002047, MelsecElement.EnumType.Word);

public static MelsecElement relayCS =

new MelsecElement("计数器触点", "CS", 0xC4, 0x000000, 0x001023, MelsecElement.EnumType.Bit);

public static MelsecElement relayCC =

new MelsecElement("计数器线圈", "CC", 0xC3, 0x000000, 0x001023, MelsecElement.EnumType.Bit);

public static MelsecElement storageCN =

new MelsecElement("计数器当前值", "CN", 0xC5, 0x000000, 0x001023, MelsecElement.EnumType.Word, 960);

public static MelsecElement relaySpecialLink =

new MelsecElement("链接特殊继电器", "SB", 0xA1, 0x000000, 0x0007FF, MelsecElement.EnumType.Bit);

public static MelsecElement storageSpecialLink =

new MelsecElement("链接特殊寄存器", "SW", 0xB5, 0x000000, 0x0007FF, MelsecElement.EnumType.Word, 960);

public static MelsecElement relayStep =

new MelsecElement("步进继电器", "S*", 0x98, 0x000000, 0x008191, MelsecElement.EnumType.Bit);

public static MelsecElement relayInputDir =

new MelsecElement("直接输入继电器", "DX", 0xA2, 0x000000, 0x001FFF, MelsecElement.EnumType.Bit);

public static MelsecElement relayOutPutDir =

new MelsecElement("直接输出继电器", "DY", 0xA3, 0x000000, 0x001FFF, MelsecElement.EnumType.Bit);

public static MelsecElement storageAddr =

new MelsecElement("变址寄存器", "Z*", 0xCC, 0x000000, 0x000015, MelsecElement.EnumType.Word, 960);

public static MelsecElement storageFile =

new MelsecElement("文件寄存器", "R*", 0xAF, 0x032767, 0x000015, MelsecElement.EnumType.Word, 960);

public static MelsecElement storageFileZ =

new MelsecElement("文件寄存器Z", "RZ", 0xB0, 0x0FE7FF, 0x000015, MelsecElement.EnumType.Word, 960);

public MelsecElement() { }

public MelsecElement(string strName, string strAscCode, int nBinCode,

int nStartAddr, int nEndAddr, EnumType enumType, int nLen=3584)

{

m_strName = strName;

m_strAscCode = strAscCode;

m_nBinCode = nBinCode;

m_nStartAddr = nStartAddr;

m_nEndAddr = nEndAddr;

m_enumType = enumType;

m_nLen = nLen;

}

public enum EnumType

{

Bit = 0,//位类型

Word = 1,//字类型

}

public string m_strName { get; set; }

public string m_strAscCode { get; set; }

public int m_nBinCode { get; set; }

public int m_nStartAddr { get; set; }

public int m_nEndAddr { get; set; }

public EnumType m_enumType { get; set; }

public int m_nLen { get; set; }//最大处理长度

}

}

2、MC二进制协议组成部分

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using TechSysWCS.Helper;

namespace TechSysWCS.Model

{

class MelsecMCBin

{

public MelsecMCBin()

{

m_nNetNo = 0x00;//本站

m_nPLCNo = 0xFF;

m_nIONo = 0xFF03;

m_nStationNo = 0x00;

m_nTimeOut = 0x1000;

m_bytelist = new List();

m_nDataLen = 12;//不包括软元件数据

}

///

/// 检查起始地址和读取长度

///

///

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)

* ***************************************************/

///

/// 构建读取字节

///

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)|写入数据(分按位和按字)

* ***********************************************************/

///

/// 构建写字节

///

/// 写入数据长度

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 m_bytelist;

public enum EnumsubTitle

{

Request = 0x5000,//请求

Respond = 0xD000,//应答

}

public enum EnumEndCode

{

Ok = 0x0000,//正常应答

Err = 0x51C0,//异常应答

}

public enum EnumCmd

{

ReadBatch = 0x0401,//成批读

WriteBatch = 0x1401,//成批写

}

///

/// 返回byte数组

///

public enum EnumSubCmd

{

/*有存储扩展模块b7=0,b6=0:随机读出,监视数据注册用外*/

Bit = 0x0001,//按位读写

Word = 0x0000,//按字读写

/*有存储扩展模块b7=1,b6=0:随机读出,监视数据注册用外*/

BitEx = 0x0081,//按位读写

WordEx = 0x0080,//按字读写

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值