三菱mc plc qt 通信协议测试程序 包含模拟工具
立即下载
资源介绍:
三菱mc plc qt 通信协议测试程序 包含模拟工具
#include "mcbinaryprotocol.h"
#include
#include
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((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(static_cast(data[i])) << (8 * i));
}
return result;
}
namespace McBinaryProtocol
{
enum PlcDataUnit
{
Bit, // 表示位
Word // 表示字
};
PlcDataUnit dataUnit;
QMap 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(0x00));
data.append(static_cast(0x00));//网路编号,上位访问下位,固定00
data.append(static_cast(0xFF));//PLC编号,上位访问下位,固定FF
//请求目标模块IO编号,表示03FF,十进制是1023。也是固定的
data.append(static_cast(0xFF));
data.append(static_cast(0x03));
data.append(static_cast(0x00));//请求目标模块站编号,上位访问下位,固定00
//请求数据长度,之后的数据长度
int datalength{0};
{
//先占位,后面计算
data.append(static_cast(0x00));
data.append(static_cast(0x00));
}
//cpu监视定时器,表示等待PLC响应的超时时间,这里是0010,十进制是16,相当与最大等待时间250ms*16=4秒;实际上PLC一般2,3个毫秒内就响应了;
data.append(static_cast(0x10));
data.append(static_cast(0x00));
datalength += 2;
//命令码,可查阅《MELSEC通信协议参考手册》第59页
//值是0401表示批量读取
data.append(static_cast(0x01));
data.append(static_cast(0x04));
datalength += 2;
//子命令,0表示按字读取(1个字=16位),1就按位读取 《MELSEC通信协议参考手册》搜索:子指令
data.append(static_cast(isBit ? 0x01 : 0x00));//
data.append(static_cast(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()<<"读取发送:"<(0x00));
data.append(static_cast(0x00));//网路编号,上位访问下位,固定00
data.append(static_cast(0xFF));//PLC编号,上位访问下位,固定FF
//请求目标模块IO编号,表示03FF,十进制是1023。也是固定的
data.append(static_cast(0xFF));
data.append(static_cast(0x03));
data.append(static_cast(0x00));//请求目标模块站编号,上位访问下位,固定00
//请求数据长度,之后的数据长度
int datalength{0};
{
//先占位,后面计算
data.append(static_cast(0x00));
data.append(static_cast(0x00));
}
//cpu监视定时器,表示等待PLC响应的超时时间,这里是0010,十进制是16,相当与最大等待时间250ms*16=4秒;实际上PLC一般2,3个毫秒内就响应了;
data.append(static_cast(0x10));
data.append(static_cast(0x00));
datalength += 2;
//命令码,可查阅《MELSEC通信协议参考手册》第59页
//值是1401表示批量写入
data.append(static_cast(0x01));
data.append(static_cast(0x14));
datalength += 2;
//子命令,0表示按字读取(1个字=16位),1就按位读取 《MELSEC通信协议参考手册》搜索:子指令
data.append(static_cast(0x00));//
data.append(static_cast(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(0x00));
data.append(static_cast(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(0x00));
data.append(static_cast(0x00));//网路编号,上位访问下位,固定00
data.append(static_cast(0xFF));//PLC编号,上位访问下位,固定FF
//请求目标模块IO编号,表示03FF,十进制是1023。也是固定的
data.append(static_cast(0xFF));
data.append(static_cast(0x03));
data.append(static_cast(0x00));//请求目标模块站编号,上位访问下位,固定00
//请求数据长度,之后的数据长度
int datalength{0};
{
//先占位,后面计算
data.append(static_cast(0x00));
data.append(static_cast(0x00));
}
//cpu监视定时器,表示等待PLC响应的超时时间,这里是0010,十进制是16,相当与最大等待时间250ms*16=4秒;实际上PLC一般2,3个毫秒内就响应了;
data.append(static_cast(0x10));
data.append(static_cast(0x00));
datalength += 2;
//命令码,可查阅《MELSEC通信协议参考手册》第59页
//值是1401表示批量写入
data.append(static_cast(0x01));
data.append(static_cast(0x14));