松下PLC与PC机的通用通讯 点击:845 | 回复:0



stonker01

    
  • 精华:0帖
  • 求助:0帖
  • 帖子:2帖 | 0回
  • 年度积分:0
  • 历史总积分:101
  • 注册:2014年11月06日
发表于:2016-09-02 10:29:55
楼主

PLC和PC机的通信,是普遍遇到的一种应用场景,对于大部分的开发者来说,实现松下协议有些复杂,现实首选的通信方式为通用协议。下面深圳智控科技的工程师就来介绍一下,当利用winpro的IEC编程环境时,怎样可以灵活的使用ST开发语言,开发出复杂的应答通信协议。

系统硬件组成和连接

 

1、FPX-C30T为系统的核心组成。

 

2、PLC使用自带的COM0。

 

3、松下的5针通信电缆用于和PC机的串口通信。

 

4、PC机采用市售的USB转232口和松下的串口线连接。



项目的建立和配置

项目的建立,选择PLC和开发语言如下


串口配置如下

 

PLCPC之间的通讯协议和数据定义

 

命令采用定长帧,PC为主,PLC为从,所有的帧都是采用应答的方式。

 

帧格式如下

PC机发送帧,长度为固定20个字节

帧头      命令      命令附加数据     LRC校验

0x25 0x25 cmdL cmdH data0 ... Data13 LRCL LRCH

动作

cmd指令代码

动作1

0x0001

动作2

0x0002

动作3

0x0003

 

PLC应答帧,长度为固定的6个字节

帧头      应答命令      LRC校验

0x25 0x25 cmdL cmdH    LRCL LRCH

正确应答时为PC机发送的命令,目前唯一的错误应答命令为0x0080帧校验错误。

 

帧头为固定的0x25 0x25,方便帧头定位。

 

五丶程序说明。

 

思路:

收字符是系统后台自动进行的,PLC程序判断收到的字符,如果字符不为帧头,0x25 0x025,则清除缓存,如果帧头则等收到20个字节后,首先判断校验码,如果校验码正确,则根据cmd指令做动作并应答,如果校验错误,则反馈给PC帧错误应答。

 

LRC

除帧头之外有效16位数据的累加和

       lrc := 0;

       fori := 1to8by1do

           lrc := lrc + recvbuff[i];

       end_for;

 

如何清除接受缓存:

使用ClearReceiveBuffer(SYS_TOOL_PORT)

 

 

如何判断收到的字符长度:

接受缓存的第一个字为收到的字符长度,例如DT100为接受缓存起始的话,那么DT100中就是接收到的字符长度。

 

如何发送字符:

使用函数

SendData(Port := SYS_TOOL_PORT, Start := sendbuff[0], NumberOfBytes := 6);

注意sendbuff[0]为发送字符的剩余数量,所以真正开始的字符要从sendbuff[1]开始。

 

从上面可以看到,winpro的开发非常类似于c语言或者basic语言的开发方式,函数指令也是很人性化的命名方式,便于开发者的记忆和使用


六、程序代码

(*初始化发送字符数组  *)

if(sys_bIsFirstScan) then

    fori := 0to9by1do

       sendbuff[i] := 0;

    end_for;

end_if;

 

(* 收到的字符串 *)

if (recvbuff[0] >= 2) then

    (* 如果收到的字符不为协议的起始,则清除收到的缓存 *)

    if (recvbuff[1] <>16#2525) then

       ClearReceiveBuffer(SYS_TOOL_PORT);

    elsif (recvbuff[0] = 18) then     

       (* 正确,则校验后处理 *)

       lrc := 0;

       fori := 1to8by1do

           lrc := lrc + recvbuff[i];

       end_for;

       if (lrc = recvbuff[9]) then

           if (recvbuff[1] = 16#0001) then

              (* 动作1处理,略*)

             

              (* 应答pc *)

              sendbuff[0] := 6;

              sendbuff[0] := 16#2525;

              sendbuff[1] := 16#0001;

              sendbuff[2] := 16#0001;

              SendData(Port := SYS_TOOL_PORT, Start := sendbuff[0], NumberOfBytes := 6);                           

           elsif (recvbuff[1] = 16#0002) then

              (* 动作2处理,略*)

             

              (* 应答pc *)

              sendbuff[0] := 6;

              sendbuff[0] := 16#2525;

              sendbuff[1] := 16#0002;

              sendbuff[2] := 16#0002;

              SendData(Port := SYS_TOOL_PORT, Start := sendbuff[0], NumberOfBytes := 6);

           elsif (recvbuff[1] = 16#0003) then

              (* 动作3处理,略*)

             

              (* 应答pc *)

              sendbuff[0] := 6;

              sendbuff[0] := 16#2525;

              sendbuff[1] := 16#0003;

              sendbuff[2] := 16#0003;

              SendData(Port := SYS_TOOL_PORT, Start := sendbuff[0], NumberOfBytes := 6);

           end_if;

 

       else

           (* 应答lrc错误 *)

           sendbuff[0] := 6;

           sendbuff[0] := 16#2525;

           sendbuff[1] := 16#0080;

           sendbuff[2] := 16#0080;

          

           SendData(Port := SYS_TOOL_PORT, Start := sendbuff[0], NumberOfBytes := 6);

       end_if;

 

       ClearReceiveBuffer(SYS_TOOL_PORT);

    end_if;

end_if;

 

 




热门招聘
相关主题

官方公众号

智造工程师