直接上干货,咱聊聊西门子1200PLC自由口通讯那点事儿。这个经典样例程序我实测过,用串口助手收发数据稳得一批,最适合刚入手的兄弟当模板用
西门子1200plc的自由口通讯经典样例程序。 该程序可用于西门子1200plc与任何设备自由口通讯,程序可作为模板,只需要轻松的修改增减报文即可使用。 本程序已测试使用串口助手与西门子1200plc进行自由口通讯的相互发送和接收数据。 采用轮询机制来实现多条报文的收发。 程序可作为模板,轻松的照着增加报文即 本程序为1200为主站,首先发送报文,从站(串口助手)接收报文,随即反馈发送给plc报文。

先看核心逻辑:主站先手发数据,从站收到后秒回。整个过程用轮询机制跑,就跟打乒乓球似的你来我往。重点是这个结构足够灵活,想加新报文直接往里塞就行,跟搭积木似的简单。

硬件组态先配好串口参数,波特率这些老生常谈的就不啰嗦了。直接看程序结构:
// 全局数据块
TYPE T_CommData :
STRUCT
SendBuffer : ARRAY[1..5] OF STRING(50); // 5条待发报文
RecvBuffer : ARRAY[1..5] OF STRING(50); // 接收缓冲区
CurrentIndex : INT := 1; // 当前处理报文序号
CommState : INT := 0; // 通讯状态机
END_STRUCT
END_TYPE
状态机才是灵魂,看这个轮询逻辑:
CASE CommState OF
0: // 初始化
TCON_CTRL(REQ:=TRUE, DONE=>#Done);
IF #Done THEN
CommState := 10;
END_IF
10: // 发送报文
IF NOT SendBusy THEN
SEND_PTP(
REQ:=TRUE,
BUFFER:=SendBuffer[CurrentIndex],
LENGTH:=LEN(SendBuffer[CurrentIndex]),
DONE=>#SendDone);
CommState := 20;
END_IF
20: // 等待发送完成
IF #SendDone THEN
RCV_PTP(ENABLE:=TRUE); // 开启接收
CommState := 30;
T#1s_Timer(IN:=TRUE); // 启动超时计时
END_IF
30: // 接收处理
IF RCV_COMPLETE OR T#1s_Timer.Q THEN
IF RCV_COMPLETE THEN
RecvBuffer[CurrentIndex] := RCV_DATA;
END_IF
CurrentIndex := CurrentIndex MOD 5 + 1; // 轮询下一个
CommState := 10;
END_IF
END_CASE
这个状态机妙在超时保护机制,1秒收不到数据自动切下条报文,防止程序卡死。SENDPTP和RCVPTP这对好基友配合默契,注意发送完成后要立即激活接收,就像发完快递得盯着物流信息一样。

重点说下数据解析的骚操作:
// 接收数据预处理
VAR
RawData : ARRAY[1..100] OF BYTE;
ASCII_Str : STRING(100);
END_VAR
FOR i := 1 TO RCV_LEN DO
ASCII_Str[i] := BYTE_TO_CHAR(RawData[i]);
END_FOR
这段把原始字节流转成ASCII字符串,实测比直接用字符串接收更稳定。特别是处理Modbus设备时,经常得拆解字节数据,这么搞准没错。

实际应用时踩过的坑:
- 报文字符串别超过硬件缓存区大小,1200的RS485模块默认是2048字节
- 发送间隔至少留50ms,给硬件缓冲腾地儿
- 用
RCV_PTP的ENABLE参数控制接收启停,比用指令触发更丝滑 - 校验和必须做!血的教训,曾经因为漏校验导致产线误动作
扩展报文数量?简单到爆:
// 新增第六条报文
SendBuffer[6] := '新的报文内容';
// 修改轮询计算
CurrentIndex := CurrentIndex MOD 6 + 1;
记住同步改接收缓冲区数组大小,别整出数组越界这种低级错误。
最后说个骚操作:用这个模板对接过扫码枪、电子秤、变频器,甚至通过转接模块跟三菱PLC搞基。关键是把对方设备的协议格式吃透,剩下的就是字符串拼接的体力活了。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)