二 系统硬件组成和连接
1丶FPX-C30T为系统的核心组成。
2丶PLC使用自带的COM0。
3丶松下的5针通信电缆用于和PC机的串口通信。
4丶PC机采用市售的USB转232口和松下的串口线连接。
三 项目的建立和配置
项目的建立,选择PLC和开发语言如下
串口配置如下
四 PLC和PC之间的通讯协议和数据定义
命令采用定长帧,PC为主,PLC为从,所有的帧都是采用应答的方式。
帧格式如下
PC机发送帧,长度为固定20个字节
帧头 命令 命令附加数据 LRC校验
0x25 0x25 cmdL cmdHdata0 ... Data13 LRCL LRCH
动作 | cmd指令代码 |
动作1 | 0x0001 |
动作2 | 0x0002 |
动作3 | 0x0003 |
PLC应答帧,长度为固定的6个字节
帧头 应答命令 LRC校验
0x25 0x25 cmdLcmdH 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;