☰
S7-1200通过TSEND_C直连PX240S标签打印配置与排错
2026/10/28 10:32:57 网站建设 项目流程

简介:面向西门子 S7-1200 PLC 与霍尼韦尔、斑马等工业标签打印机联调的实操型教程,适合已具备博图基础、需要打通以太网打印链路的自动化工程师与设备调试人员。内容围绕打印机 IP 与端口配置、ZSim 指令语言切换、ZPL-II 标签指令获取、博图 TSEND_C 通信组态、字符串数据块与绝对寻址、标签编码生成及测试验证展开,重点说明默认端口与西门子通信端口范围的差异,以及优化块访问等易错点。资源包仅含 1 个 PDF 文件,大小约 721KB,便于随身查阅和按章节对照调试。已有 1660 人学习,说明该场景具有较强通用性。读者可从中获得从打印机参数设置到 PLC 发送打印指令的完整思路,理解 Zebra Designer 生成 ZPL-II 代码并转存至 DB 的方法,也能借鉴编码唯一性设计与格式切换的实现方式,减少现场联调时的反复试错。

1. 一条网线接上 1215PLC 和 PX240S:程序没错,端口先翻车

前阵子调一条贴标线,1215PLC 用 TCP 直连标签打印机,博图里 TSEND_C 的状态码卡在 8090 一动不动,IP 能 ping 通、网线换了两根、程序翻了三遍,最后发现打印机端口还停在出厂默认的 9100。S7-1200 的以太网通信端口只认 0 到 5000,而工业标签机默认基本都在 9000 往上,就这一个数字,能让整条链路停在“连不上”。这套组合在贴标、外箱打印、喷码工位很常见:西门子 1200 用 TCP 把 ZPL-II 指令直接丢给霍尼韦尔 PX240S,打印机内部切到斑马指令集,省掉中间件和一台工控机。装顺了十分钟出第一张标签,装不顺就是三种结局——连不上、连上不出纸、出纸乱码。下面按我实际装过一遍的顺序,把环境、打印机参数、ZPL 取码、博图组态和排错一次讲清,适合手头有 1215C、一台带网口的工业标签机、想自己把这条链路搭起来的现场调试人员。

2. 硬件与网络清单:1215PLC、PX240S 和 5000 以内的端口怎么定

这一章先把“装什么、地址怎么排”定死。很多人一上来就打开博图写程序,结果打印机 IP 是 192.168.1.x、PLC 是 192.168.0.x,两个网段互相看不见,后面所有步骤都白做。我的习惯是先列一张设备表,把 IP、掩码、端口写在纸上,再动手。

2.1 硬件核对:PLC、打印机接口与网线

这套方案对硬件的要求不高,但有两个前提必须满足:PLC 要有以太网口,打印机要有以太网口。1215C 自带两个 RJ45(PROFINET 接口),打印机侧 PX240S 是工业机型,串口和以太网口都带。两边都有网口,才能走 TCP 直连。

设备型号/角色接口说明
控制器CPU 1215C(S7-1200 系列)集成 PROFINET 口 ×2用其中一个口接打印机所在交换机
打印机霍尼韦尔 PX240S串口 + 以太网命令语言需切到 ZSim,兼容 ZPL-II
调试电脑装 TIA Portal 与 Designer普通网口临时接入同网段,配完可撤
网线超五类直通线RJ45打印机到交换机、PLC 到交换机

1215C 的两个网口可以级联,现场没有交换机时,可以把打印机直接插在 PLC 的第二个口上,省一台设备。我一般还是加一台小交换机,调试电脑能同时看到两边,抓包、ping、开打印机 Web 页面都方便。硬件接好后先别通电写程序,把电脑网卡改成和打印机同网段,浏览器能打开打印机页面,这一步过了再往下走。

2.2 打印机 IP、网关与子网

打印机地址在触摸屏上设,路径是“通信设置 → 配置通信地址”,填 IP 和子网掩码,网关默认空着就行。原文测试用的是 192.168.2.88,这个地址可以照抄,但要注意别和现场已有的设备撞。我给一组自己常用的地址规划:

设备IP子网掩码备注
CPU 1215C192.168.2.10255.255.255.0在博图硬件组态里设,不在打印机里设
标签打印机192.168.2.88255.255.255.0触摸屏里设,网关留空
调试电脑192.168.2.100255.255.255.0临时用,配完改回自动获取

设完 IP 后,用电脑 ping 一下 192.168.2.88,能通再继续。这里有个小坑:打印机改完 IP 不会立刻生效,要退出配置界面并确认保存,有的固件还会提示重启网络,不重启的话旧地址还能 ping 通、新地址反而没反应,很容易误判成“地址设错了”。

2.3 端口号从 9100 改到 5000 以内

这是整套方案里最容易翻车的一步,也是我开头那段血泪经验的来源。打印机出厂默认的通信端口是 9000 多(不同固件不一样,常见 9100),而西门子以太网通信的端口范围是 0 到 5000,两边对不上,TSEND_C 永远建不了连接。

改法不复杂:打印机用网线连电脑,浏览器输入打印机 IP(测试环境是 192.168.2.88),进通信配置页,把端口号改成小于 5000 的值。我一般填 4999,留一点余量,不让它顶到边界上。

参数出厂常见值改成原因
通信端口9100 或 9000+4999(任意 <5000)西门子以太网通信端口范围 0-5000
协议RAW TCPRAW TCP保持原样,ZPL 走裸 TCP
IP192.168.2.88不变与 PLC 同网段

改完保存,打印机侧这块就算落地了。后面博图里 CONNECT 参数的 RemotePort 必须和这里填的一模一样,差一位都连不上。我见过有人打印机改成了 4999,程序里还写着 9100,查了两小时。

2.4 命令语言切到 ZSim 并保存

端口通了只是链路通,打印机认不认你发的指令是另一回事。PX240S 默认跑自己的指令集,你把斑马的^XA发过去,它要么忽略,要么打出一串原文。必须把命令语言切到 ZSim,这是霍尼韦尔对 ZPL-II 的兼容模式。

路径是“系统设置 → 常规 → 命令语言 → 选择 ZSim”,选完退出时系统会问是否保存,一定选“是”。这一步界面提示很弱,点快了直接退出,重启后还是原语言,前面配的全白费。切完之后建议打一张自检页,看页脚或配置信息里命令语言那一栏是不是 ZSim,确认了再回 PLC 侧。

注意:命令语言和端口是两条独立的线,端口对了但语言没切,现象是“连上了、指令发出去了、打印机没反应”,和第 5 章里的第 2 条对得上,排查时先看这里。

3. 标签模板到 ZPL-II 指令码:Designer 打印到文件这一步别漏

打印机参数配好,接下来要解决“发什么”。PLC 里不能手写整段 ZPL,得先用标签设计软件把模板画出来,再导出成指令码。这一步的核心动作只有一个:打印到文件,而不是真的打到打印机。

3.1 装 Designer 2 或 Designer PRO,先按标签纸建模板

软件用 Zebra Designer 2 或 Designer PRO 都行,版本上不用追新,能导出 ZPL 就可以。装完先确认菜单里有“打印到文件”这个选项,没有的话说明版本或授权不对,换一个再装,别在这上面耗。

建模板时按实际标签纸来:宽度、高度、间隙(gap)三项要和纸卷一致,这几项直接决定导出的^PW(打印宽度)和^LL(标签长度)。然后是内容:固定文字、条码、可变编码。原文里编码选的是“固定式”,意思是编码位数固定,比如 9 位数字,这样 PLC 侧替换时不用改长度,寻址简单。字体、字号、条码类型都可以在界面里调,调完先在 Designer 里预览,确认布局没跑偏再导出。

模板里要给可变编码留位置,我一般用一段占位符,比如000000001,导出后到记事本里把这一段换成 PLC 侧的变量。这样模板和程序是解耦的,改标签样式只动 Designer,改编码规则只动 PLC。

3.2 打印到文件:勾选项和文件位置

模板画完,点打印,打印机选“打印到文件”或者 File 端口,保存到桌面。这里有个关键勾选项:必须勾上“打印到文件”生成 ZPL 指令,不勾的话软件走的是驱动,导出的可能是图形数据而不是指令码。

  • 打印机选择:File / 打印到文件
  • 保存位置:桌面,方便记事本打开
  • 文件格式:.prn或.txt都行,本质是文本

导出后文件不大,几 KB 到几十 KB。如果导出的文件打开是乱码,说明存成了二进制或图形格式,回去检查是不是选错了输出方式。正常情况用记事本打开,能看到以^XA开头、^XZ结尾的一整段文本,中间是^FO、^A0N、^FD、^FS这些指令。

3.3 用记事本取码,按变量切分

打开导出的文件,看到的是一整条 ZPL-II 指令。下面是我按原文格式整理的一个示意片段,实际内容以 Designer 导出为准:

^XA ^PW812 ^LL1218 ^FO50,50^A0N,40,40^FDWO-^FS ^FO50,110^A0N,40,40^FD000000001^FS ^FO50,200^BY3^BCN,100,Y,N,N^FD000000001^FS ^XZ

逐行说明:^XA是标签开始,^XZ是标签结束,这两行必须成对出现;^PW812是打印宽度 812 点(203dpi 下约 4 英寸),^LL1218是标签长度;^FO50,50是坐标定位;^A0N,40,40是字体和大小;^FD...^FS是一段字段内容,中间夹的就是要替换的编码;^BY3和^BCN是条码参数。

拿到这段之后,要做的事是“切两刀”:把编码前面的固定指令放一段,编码本身放一段,编码后面的收尾指令放一段。这样 PLC 里只需要改中间那段,不用每次重拼整条。注意^、,、-这些符号在字符串里原样保留,S7-1200 的 string 用单引号括起来就行。还有一点,如果标签里有中文,导出后要核对字符集指令(常见^CI28)和字体是否随指令一起下发,纯数字编码最省事,现场能不用中文就不用。

4. 博图组态与打印程序:TSEND_C、7004、DB 去优化和 string 拼码

指令码有了,剩下就是让 PLC 把它发出去。这一章是整套方案里代码量最大的部分,核心是三件事:建连接、拼字符串、看状态码。

4.1 硬件组态与连接参数

博图里新建项目,加 CPU 1215C,在硬件组态里把 PROFINET 接口的 IP 设成 192.168.2.10,和打印机同网段。然后写通信程序,指令用 TSEND_C。选它的原因很直接:这一条指令把建立连接、断开连接、发送数据三件事都包了,不用像 TCON + TSEND 那样两步走,现场调试少一个环节就少一个出错点。

连接参数用TCON_IP_v4结构,我一般在全局 DB 里建一个变量,逐项填:

参数填写值说明
InterfaceId64(以实际硬件标识符为准)点 CPU 的 PROFINET 接口,在属性里看硬件标识符
ID1连接号,项目内唯一即可
ConnectionType11TCP 连接类型
ActiveEstablishedTRUEPLC 作为主动连接方
RemoteAddress192.168.2.88打印机 IP,四段分别填
RemotePort4999必须和打印机侧改过的端口一致,且小于 5000
LocalPort2000本地端口,避开已占用即可

InterfaceId 这一项最容易填错,不同项目的硬件标识符不一样,照抄别人的 64 有可能编译不过。正确做法是打开设备组态,点 CPU 上的绿色网口,看属性里的“硬件标识符”,把那个数填进去。

4.2 TSEND_C 参数逐项填

参数结构建好后,在 OB1 或 FB 里调用 TSEND_C。下面是我实际用的 SCL 写法,引脚名和博图里一致:

// 调用 TSEND_C,CONT 常 TRUE 保持连接 "TSEND_C_DB"( REQ := "SendReq", // 上升沿触发一次发送 CONT := TRUE, // 保持连接,不断线 CONNECT := "TCP_Conn_DB", // TCON_IP_v4 结构 DATA := "SendBuffer".ZPL_Full, // 要发送的字符串 LEN := "SendBuffer".SendLen, // 发送字节数 DONE => "SendDone", BUSY => "SendBusy", ERROR => "SendError", STATUS => "SendStatus");

逐项说:REQ要的是一个上升沿,不是电平,一直给 TRUE 只发一次,下次要复位再置位;CONT := TRUE让连接保持常开,不然每发一次断一次,打印机侧会频繁重建连接;CONNECT指向 4.1 建的结构;DATA指向 DB 里的字符串变量;LEN是实际发送的字节数,ASCII 字符下字符数等于字节数,有中文就得按字节算,别直接拿字符数糊弄。

发送流程是:REQ上升沿 →BUSY置 1 → 发完DONE置 1、STATUS回 0000 → 把REQ复位,等下一次。如果ERROR置 1,直接看STATUS的十六进制值,比猜快得多。

4.3 状态码 7004 意味着什么

连接建起来后,STATUS会停在 16#7004。这个值的含义是“连接已建立,等待发送作业”,注意它只说明链路通了,数据还没发。很多人看到 7004 就以为打印完了,回头发现打印机没出纸,其实是REQ根本没给上升沿。

我在现场的判断顺序是这样的:

  1. ERROR = 1:看STATUS,多半是端口不对、IP 不通、连接号冲突;
  2. BUSY = 1:在发,等;
  3. STATUS = 7004且REQ没有上升沿:查触发条件,触摸屏按钮或计数到达有没有真的给信号;
  4. DONE = 1:这一笔发完了,核对打印机是否出纸。

7004 是“待命”,不是“完成”,这两个状态混了,排查方向会完全跑偏。

4.4 DB 去优化与 string 拼码

发送的数据放在全局 DB 里,这个 DB 有一个必须改的属性:取消“优化的块访问”。优化块里的变量只有符号地址,绝对地址不固定,后面想按字节改编码、用 BLKMOV 搬数据都会翻车。改法是右键 DB → 属性 → 取消勾选“优化的块访问”,然后重新编译。

DB 结构我一般拆成四段,头、编码、尾、拼好的整条:

ZPL_Head String[120] // ^XA 到编码前的固定指令 CodePos String[12] // 9 位编码,留点余量 ZPL_Tail String[80] // 编码后的收尾指令 ZPL_Full String[254] // 拼接结果,S7-1200 单字符串上限 254 SendLen Int // 实际发送字节数

拼码用 CONCAT,分两次拼,避免长度算错:

// 先拼头和编码,再拼尾 "SendBuffer".ZPL_Full := CONCAT(IN1 := "SendBuffer".ZPL_Head, IN2 := "SendBuffer".CodePos); "SendBuffer".ZPL_Full := CONCAT(IN1 := "SendBuffer".ZPL_Full, IN2 := "SendBuffer".ZPL_Tail); "SendBuffer".SendLen := LEN("SendBuffer".ZPL_Full);

逻辑说明:CONCAT 把两段字符串接起来,第一次拼出“头 + 编码”,第二次接上“尾”,最后用 LEN 取长度填到发送引脚。参数上唯一要盯的是 DB 里String[254]的上限,整条 ZPL 超了 254 字符就得拆成两包发,或者精简指令里的空白字段。

顺带说一下 char 和 string 的取舍。原文提到两种都测过:单字符 char 发送,改编码时寻址简单,但写入要一个一个来,9 位编码就是 9 次赋值,繁琐;string 一次拼好,代码短,代价是长度要算准。现场我选 string,因为标签格式一变,char 那套赋值语句全要重写。

4.5 多格式切换与计数

一个工位往往不止一种标签,外箱、内盒、客户专用格式各一套 ZPL。我的做法是在中间 DB 里按格式号存多组头尾指令,触摸屏给一个格式代号,程序里用 CASE 选:

// 格式号来自触摸屏,1/2/3 对应不同标签 CASE "FormatNo" OF 1: "SendBuffer".ZPL_Head := "FmtDB".Head1; "SendBuffer".ZPL_Tail := "FmtDB".Tail1; 2: "SendBuffer".ZPL_Head := "FmtDB".Head2; "SendBuffer".ZPL_Tail := "FmtDB".Tail2; 3: "SendBuffer".ZPL_Head := "FmtDB".Head3; "SendBuffer".ZPL_Tail := "FmtDB".Tail3; END_CASE;

这样加一种标签只需要在 DB 里加一组头尾,程序结构不动。编码部分用计数生成,测试时是从 1 开始累加的 9 位数字,实际项目里要保证唯一性,可以在计数前拼上班次号或日期。

// 9 位编码:累加后左补零,取右 9 位 "Counter" := "Counter" + 1; "SendBuffer".CodePos := RIGHT(IN := CONCAT(IN1 := '000000000', IN2 := DINT_TO_STRING("Counter")), L := 9);

逻辑说明:先补九个零再拼上数字,然后从右边取 9 位,得到000000001这种固定长度编码。参数上注意两处:RIGHT的 L 要等于编码位数,模板里^FD后的位数也要一致。原文特别提过,编码位数从 9 位改成别的位数后,写编码的那段程序要同步改,指的就是这里。

5. 常见问题排查:端口、语言、指令码、DB 访问四类翻车

这套链路我前后装过几次,出问题的位置高度集中,基本跑不出下面五条。每一条都按“现象 → 原因 → 解决”记,现场照着对就行。

5.1 现象:TSEND_C 一直报错,7004 迟迟不来

现象是ERROR置 1,STATUS显示 8090 或 80C8 之类的值,等多久都到不了 7004。原因通常有三个:打印机端口还是 9000 多、PLC 和打印机不在同一网段、打印机网口没通。前两个占九成。

解决顺序:先用电脑 ping 打印机 IP,通了说明网络层没问题;再打开打印机配置页核对端口是不是小于 5000;最后回博图看 CONNECT 里的 RemotePort 和 RemoteAddress 是否和打印机一致。这三步走完还报错,换一根网线,直通线和交叉线的老问题在工业现场偶尔还能碰到。

5.2 现象:7004 有了,REQ 也给了,打印机不出纸

状态码停在 7004,手动触发REQ后DONE也置 1 了,但打印机一点动静没有。原因多半是命令语言没切到 ZSim,打印机把^XA当成无法识别的指令直接丢弃;也可能是端口连上了但不是打印服务端口。

解决:回打印机“系统设置 → 常规 → 命令语言”,确认是 ZSim,退出时选保存,然后打一张自检页确认。自检页上会打印当前命令语言,看一眼比猜十次快。切完重启打印机,再触发一次发送。

5.3 现象:出纸了,但打出来是乱码或者半截

纸张出来了,上面印的是^XA^FO这样的原文,或者只打了半张就停。原因有三个方向:指令码里混进了 Designer 的驱动头、文件里有多余的全角符号或换行、LEN填的长度比实际字符串短。

解决:记事本打开导出的文件,只保留^XA到^XZ这一段,前后多余内容删掉;检查有没有中文全角标点混进指令;核对LEN是不是按实际字符数给的。半截打印基本都是长度不够,把SendLen在线监控一下,和字符串实际长度对一遍。

5.4 现象:改了编码位数,打印出来还是旧位数

客户要求从 9 位改成 12 位,程序里改了计数,打出来还是 9 位。原因是三处没同步:Designer 模板里^FD后的占位符位数、SCL 里RIGHT的 L 参数、DB 里CodePos的字符串长度。改一处不管用。

解决:三处一起改。模板重新导出 ZPL,RIGHT的 L 改成 12,CodePos从String[12]扩到String[16]留余量。改完重新编译下载,别只下载程序块不下载 DB,DB 结构变了不重新初始化,里面还是旧长度。

5.5 现象:DB 绝对寻址编译报错,或者运行值不对

想按字节改编码,编译提示无法绝对寻址,或者在线监控看到的值和写进去的对不上。原因就一个:DB 还是“优化的块访问”。

解决:右键 DB → 属性 → 取消“优化的块访问”,确定后重新编译整个项目。这一步改完,DB 里变量的偏移量才是固定的,后面用 BLKMOV 或者按偏移写数据才靠谱。改完记得重新下载 DB,只下载 OB 不生效。

6. 验证跑通:从 7004 到第一张标签落地

装完不等于跑通,我一般按下面这张表逐项过一遍,全绿才算收工。

验证项操作期望结果不通过看哪
网络连通电脑 ping 打印机 IP有回复网段、网线、打印机 IP 是否保存
端口一致打印机配置页 vs CONNECT.RemotePort都小于 5000 且相同第 5.1 条
连接建立在线监控 TSEND_CSTATUS = 7004CONNECT 参数、InterfaceId
单次发送手动给 REQ 一个上升沿BUSY 一闪,DONE = 1REQ 是否复位、LEN 是否够
出纸内容看第一张标签编码位数、条码可扫第 5.3、5.4 条
编码递增再触发一次编码 +1,位数不变计数与 RIGHT 的 L
断电保持打印机重启端口、ZSim 仍在退出时是否选保存

这张表里最容易被跳过的是最后一行。调试时一切正常,现场一断电,打印机参数回到出厂,端口又变回 9100,第二天开机整条线停摆。我吃过这个亏,现在每次配完都强制断电重启一次,确认参数还在才签字。

还有一个习惯:第一次跑通后,别急着让触摸屏自动触发。先手动给REQ发三到五次,每次核对打出来的编码是不是连续、条码能不能扫、纸张定位有没有偏移。自动流程一开,问题会被节拍掩盖,等到批量生产才发现编码重复或者漏打,回头查更麻烦。

从那以后我每次上电都按固定顺序走一遍:先看 7004 到没到,再手动触发一次REQ看DONE,最后才把触摸屏的自动发送打开。这个顺序看着笨,但能把“连接问题”和“打印问题

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询