三菱mc plc qt 通信协议测试程序 包含模拟工具
资源内容介绍
三菱mc plc qt 通信协议测试程序 包含模拟工具 #include "mcbinaryprotocol.h"#include <QDebug>#include <QBitArray>const QString C = "C";const QString D = "D";const QString L = "L";const QString M = "M";const QString T = "T";const QString S = "S";const QString X = "X";const QString Y = "Y";const QString B = "B";const QString F = "F";const QString Z = "Z";const QString R = "R";const QString TN = "TN";const QString CN = "CN";QByteArray intToQByteArray(qint32 number, qint32 size){ QByteArray data(size, 0); for (int i = 0; i < size; ++i) { data[i] = static_cast<char>((number >> (8 * i)) & 0xFF); } return data;}qint32 QByteArrayToInt(const QByteArray& data){ qint32 result = 0; int size = data.size(); for (int i = 0; i < size; ++i) { result |= (static_cast<qint32>(static_cast<uchar>(data[i])) << (8 * i)); } return result;}namespace McBinaryProtocol{ enum PlcDataUnit { Bit, // 表示位 Word // 表示字 }; PlcDataUnit dataUnit; QMap<QString,char> softCodeMap; QByteArray read_word(char areaTag,int startAddress,int length,bool isBit); QByteArray write_word(char areaTag, int startAddress, qint32 value); QByteArray write_bit(char areaTag, int startAddress, bool value);}void McBinaryProtocol::initSoftCode(){ //区域代码《MELSEC通信协议参考手册》第68页 softCodeMap[D] = 0xA8; //数据寄存器 softCodeMap[M] = 0x90; //内部继电器 softCodeMap[X] = 0x9c; //输入 softCodeMap[Y] = 0x9d; //输出 softCodeMap[L] = 0x92; //锁存继电器 softCodeMap[B] = 0xA0; //链接继电器 softCodeMap[F] = 0x93; //报警器 softCodeMap[Z] = 0xCC; //变址寄存器 softCodeMap[R] = 0xAF; //文件寄存器 softCodeMap[TN] = 0xC2; //定时器 softCodeMap[CN] = 0xC5; //计数器}QByteArray McBinaryProtocol::read_word(char areaTag, int startAddress, int length, bool isBit){ dataUnit = isBit ? Bit : Word; QByteArray data; //发起指令,固定 50 00 data.append(0x50); data.append(static_cast<char>(0x00)); data.append(static_cast<char>(0x00));//网路编号,上位访问下位,固定00 data.append(static_cast<char>(0xFF));//PLC编号,上位访问下位,固定FF //请求目标模块IO编号,表示03FF,十进制是1023。也是固定的 data.append(static_cast<char>(0xFF)); data.append(static_cast<char>(0x03)); data.append(static_cast<char>(0x00));//请求目标模块站编号,上位访问下位,固定00 //请求数据长度,之后的数据长度 int datalength{0}; { //先占位,后面计算 data.append(static_cast<char>(0x00)); data.append(static_cast<char>(0x00)); } //cpu监视定时器,表示等待PLC响应的超时时间,这里是0010,十进制是16,相当与最大等待时间250ms*16=4秒;实际上PLC一般2,3个毫秒内就响应了; data.append(static_cast<char>(0x10)); data.append(static_cast<char>(0x00)); datalength += 2; //命令码,可查阅《MELSEC通信协议参考手册》第59页 //值是0401表示批量读取 data.append(static_cast<char>(0x01)); data.append(static_cast<char>(0x04)); datalength += 2; //子命令,0表示按字读取(1个字=16位),1就按位读取 《MELSEC通信协议参考手册》搜索:子指令 data.append(static_cast<char>(isBit ? 0x01 : 0x00));// data.append(static_cast<char>(0x00)); datalength += 2; //首地址 { data.append(intToQByteArray(startAddress,3)); datalength += 3; } //软元件,表示读取PLC寄存器的类型。A8表示D点;其他常见的有: 90-M点;9C-X点;9D-Y点;B0-ZR外部存储卡 data.append(areaTag); datalength += 1; //读取长度 { data.append(intToQByteArray(length,2)); datalength += 2; } { auto temp = intToQByteArray(datalength,2); data[7] = temp[0]; data[8] = temp[1]; } qDebug()<<"读取发送:"<<data.toHex(':'); return data;}QByteArray McBinaryProtocol::write_word(char areaTag,int startAddress,qint32 value){ QByteArray data; //发起指令,固定 50 00 data.append(0x50); data.append(static_cast<char>(0x00)); data.append(static_cast<char>(0x00));//网路编号,上位访问下位,固定00 data.append(static_cast<char>(0xFF));//PLC编号,上位访问下位,固定FF //请求目标模块IO编号,表示03FF,十进制是1023。也是固定的 data.append(static_cast<char>(0xFF)); data.append(static_cast<char>(0x03)); data.append(static_cast<char>(0x00));//请求目标模块站编号,上位访问下位,固定00 //请求数据长度,之后的数据长度 int datalength{0}; { //先占位,后面计算 data.append(static_cast<char>(0x00)); data.append(static_cast<char>(0x00)); } //cpu监视定时器,表示等待PLC响应的超时时间,这里是0010,十进制是16,相当与最大等待时间250ms*16=4秒;实际上PLC一般2,3个毫秒内就响应了; data.append(static_cast<char>(0x10)); data.append(static_cast<char>(0x00)); datalength += 2; //命令码,可查阅《MELSEC通信协议参考手册》第59页 //值是1401表示批量写入 data.append(static_cast<char>(0x01)); data.append(static_cast<char>(0x14)); datalength += 2; //子命令,0表示按字读取(1个字=16位),1就按位读取 《MELSEC通信协议参考手册》搜索:子指令 data.append(static_cast<char>(0x00));// data.append(static_cast<char>(0x00)); datalength += 2; //首地址 { data.append(intToQByteArray(startAddress,3)); datalength += 3; } //软元件,表示读取PLC寄存器的类型。A8表示D点;其他常见的有: 90-M点;9C-X点;9D-Y点;B0-ZR外部存储卡 data.append(areaTag); datalength += 1; //每次固定写入一个 //注意,这里和位的不一样,位是0x01在前面 data.append(static_cast<char>(0x00)); data.append(static_cast<char>(0x01)); datalength += 2; data.append(intToQByteArray(value,2)); datalength += 2; { auto temp = intToQByteArray(datalength,2); data[7] = temp[0]; data[8] = temp[1]; } return data;}QByteArray McBinaryProtocol::write_bit(char areaTag, int startAddress, bool value){ QByteArray data; //发起指令,固定 50 00 data.append(0x50); data.append(static_cast<char>(0x00)); data.append(static_cast<char>(0x00));//网路编号,上位访问下位,固定00 data.append(static_cast<char>(0xFF));//PLC编号,上位访问下位,固定FF //请求目标模块IO编号,表示03FF,十进制是1023。也是固定的 data.append(static_cast<char>(0xFF)); data.append(static_cast<char>(0x03)); data.append(static_cast<char>(0x00));//请求目标模块站编号,上位访问下位,固定00 //请求数据长度,之后的数据长度 int datalength{0}; { //先占位,后面计算 data.append(static_cast<char>(0x00)); data.append(static_cast<char>(0x00)); } //cpu监视定时器,表示等待PLC响应的超时时间,这里是0010,十进制是16,相当与最大等待时间250ms*16=4秒;实际上PLC一般2,3个毫秒内就响应了; data.append(static_cast<char>(0x10)); data.append(static_cast<char>(0x00)); datalength += 2; //命令码,可查阅《MELSEC通信协议参考手册》第59页 //值是1401表示批量写入 data.append(static_cast<char>(0x01)); data.append(static_cast<char>(0x14));