二 系統硬件組成和連接
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;