S7-200 PLC 与 PC自由口通讯 协议定义与协议解析C#实现

S7-200 PLC自由口通讯协议解读(其本质为串口通讯,可使用串口通讯工具进行调试)
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);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值