S7-200 PLC自由口通讯协议解读(其本质为串口通讯,可使用串口通讯工具进行调试)
PLC端定义协议如下:
PC端解读协议代码如下:
声明INIT_DATA 和 Revdata模块 共同定义的数据类型
//{61 M2 M3 M4 M5 VW304 VW306 CRC 62}
public static byte[] XMT_PLC_MSG = { 0x61
, 0x00 //M2 .0 A机型 .1 B机型 .2 C机型 .3 油门拉紧 .4 油门松开 .5 PC_停止测试 .6 PC_暂停测试
, 0x00 //M3 .5 负载1_100W .6 负载2_200W .7 负载3_200W
, 0x00 //M4 .0 k线开关 .1 机械_电子油门(0机械,1电子) .2 PC补水控制 .3 PC停止补水 .4 PC补油控制 .5 PC停止补油
, 0x00 //M5
, 0x00, 0x00 //VW304 自动油门开度
, 0x01, 0xF4 //VW306 停止加热温度 50
, 0x00, 0x00 //CRC 校验和
, 0x62 };
调用串口发送命令向PLC发送指令
serialPort1.Write(XMT_PLC_MSG, 0, XMT_PLC_MSG.Length);
调用串口接收命令,接收在DATA_ASC中定义的 PLC发给PC的数据
//byte[] RCV_DATA_TMP = new byte[63];
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
B_RCV_PLC = true;
int length = serialPort1.BytesToRead;
byte[] data = new byte[length];
if (length > 0)
{
serialPort1.Read(data, 0, length);
serialPort1.DiscardInBuffer();
bool RCV_ERROR = false;
if (length == 7) //防止错误代码
{
if (data[5] == 0x4F & data[6] == 0x4B & RCV_COUNT != 56)
{
RCV_COUNT = 0;
RCV_ERROR = true;
}
}
if (!RCV_ERROR)
{
for (int i = 0; i < length; i++)
{
if (RCV_COUNT < 63) RCV_PLC_MSG[RCV_COUNT] = data[i];
RCV_COUNT++;
}
}
}
if (RCV_COUNT >= 63)//所需数据完整接收,63byte
{
RCV_COUNT = 0;
lock (RCV_PLC_MSG_) RCV_PLC_MSG_ = RCV_PLC_MSG;
RCV_PLC_MSG_EXPL(); //调用数据解析
}
B_RCV_PLC = false;
}
DATA_ASC数据解析函数
/**解读出byte数据表示的信息*************/
private void RCV_PLC_MSG_EXPL()
{
lock (RCV_PLC_MSG_)
{
byte[] RCV_CRC = PLC_CRC(RCV_PLC_MSG_, 1, 58);
if (RCV_CRC[0] == RCV_PLC_MSG_[59] & RCV_CRC[1] == RCV_PLC_MSG_[60])
{
S7200Data.Key_Ready = GETBIT(RCV_PLC_MSG_[2], 5) & GETBIT(RCV_PLC_MSG_[5], 4); //I1.5 ?I4.4
S7200Data.Key_Start = GETBIT(RCV_PLC_MSG_[2], 6) | GETBIT(RCV_PLC_MSG_[5], 5); //I1.6 ?I4.5
S7200Data.Key_Stop = GETBIT(RCV_PLC_MSG_[1], 5) | GETBIT(RCV_PLC_MSG_[4], 5); //I0.5 ?I3.5
S7200Data.B_OilPressLow = !GETBIT(RCV_PLC_MSG_[2], 0); //I1.0;
S7200Data.B_Request_DrainWater = GETBIT(RCV_PLC_MSG_[6], 6) | GETBIT(RCV_PLC_MSG_[8], 6) | GETBIT(RCV_PLC_MSG_[9], 4);//Q0.6 Q2.6 Q3.4
S7200Data.B_Request_DrainFuel = GETBIT(RCV_PLC_MSG_[8], 7) | GETBIT(RCV_PLC_MSG_[7], 1); //Q1.1 Q2.7
S7200Data.PreWater = RCV_PLC_MSG_[13] * 256 + RCV_PLC_MSG_[14]; //AIW0
S7200Data.PWO = RCV_PLC_MSG_[15] * 256 + RCV_PLC_MSG_[16];
S7200Data.PFUEL = RCV_PLC_MSG_[17] * 256 + RCV_PLC_MSG_[18];
S7200Data.ChargV = ((RCV_PLC_MSG_[25] * 256 + RCV_PLC_MSG_[26]);
S7200Data.TempTank = RCV_PLC_MSG_[41] * 256 + RCV_PLC_MSG_[42];
S7200Data.ChargI = RCV_PLC_MSG_[23] * 256 + RCV_PLC_MSG_[24];
S7200Data.FueLevel = RCV_PLC_MSG_[35] * 256 + RCV_PLC_MSG_[36];
S7200Data.AD1 = RCV_PLC_MSG_[19] * 256 + RCV_PLC_MSG_[20];
S7200Data.AD2 = RCV_PLC_MSG_[21] * 256 + RCV_PLC_MSG_[22];
S7200Data.AD3 = RCV_PLC_MSG_[27] * 256 + RCV_PLC_MSG_[28];
S7200Data.START_I = RCV_PLC_MSG_[29] * 256 + RCV_PLC_MSG_[30];
S7200Data.BATTER_V = RCV_PLC_MSG_[31] * 256 + RCV_PLC_MSG_[32];
S7200Data.AD4 = RCV_PLC_MSG_[33] * 256 + RCV_PLC_MSG_[34];
S7200Data.TWI = RCV_PLC_MSG_[37] * 256 + RCV_PLC_MSG_[38];
S7200Data.TWO = RCV_PLC_MSG_[39] * 256 + RCV_PLC_MSG_[40];
S7200Data.T1 = RCV_PLC_MSG_[43] * 256 + RCV_PLC_MSG_[44];
S7200Data.T_EXH = RCV_PLC_MSG_[45] * 256 + RCV_PLC_MSG_[46];
S7200Data.T2 = RCV_PLC_MSG_[47] * 256 + RCV_PLC_MSG_[48];
S7200Data.T3 = RCV_PLC_MSG_[49] * 256 + RCV_PLC_MSG_[50];
S7200Data.T4 = RCV_PLC_MSG_[51] * 256 + RCV_PLC_MSG_[52]; //AIW38
S7200Data.B_NoCharging = (S7200Data.ChargI < 1);
}
}
}