在项目里用欧姆龙CP1H去跟台达VFD-M变频器做自由口通讯很多人第一反应是“这还要写教程”但真到了现场你会发现值得踩的坑一个都不少自由口模式下报文怎么组织、CRC高低字节往哪儿放、变频器参数有没有切到通讯模式、RS485正负接反、寄存器地址差一位……随便哪一个都能让你白折腾半天。这篇文章就从一个实际用CP1H无协议通讯接台达VFD-M变频器的例子入手把从硬件接线、变频器参数设置、Modbus报文组装到梯形图程序实现的完整链路走一遍顺手把那些“手册不会明说”的经验一并交代了。适读人群正在用欧姆龙CP1H做主站、想控制台达变频器的一线电气工程师或者刚接触自由口通讯、对Modbus RTU报文体感还不够深的新手。文章里的程序思路不挑PLC品牌换成其他支持无协议串口收发的PLC也能照搬。1. 通讯方案整体设计思路为什么用自由口做Modbus1.1 应用场景与需求拆解最常见的使用场景是这样一台机器上有欧姆龙CP1H做逻辑控制旁边是一台台达VFD-M变频器带着电机跑HMI或者上位机要求能远程设定频率、启停电机、再读回实际频率和电流。要实现这个功能方案其实有好几条。一是给CP1H加一块专用的Modbus-RTU从站/主站模块但成本上去了而且CP1H本体不少型号并没有现成的Modbus主站扩展模块可用得靠功能块去模拟。二是用CP1H自带的串口做HOST Link跟触摸屏通讯让屏直接去读变频器但这样PLC程序里拿不到变频器的实时数据后续做逻辑联动比如频率到了才允许动作就非常别扭。所以最务实的就是第三条路把CP1H的串口设置为“无协议”通讯模式用自由口方式自己组织Modbus RTU报文CP1H作为主站去轮询台达VFD-M。1.2 自由口通讯的本质自由口通讯这个词听起来玄乎本质上就是一句话串口不再跑固定的HOST Link协议而是完全由用户程序决定发什么字节、收什么字节。欧姆龙CP1H里实现收发就两条指令TXD发送、RXD接收。你把一串数据放到数据区里TXD把它从串口发出去变频器回的数据进了串口寄存器RXD再把它读进数据区。Modbus RTU是一个极其简单的协议一帧报文就是“从站地址 功能码 数据 16位CRC校验”。它天然适合用自由口做因为报文本身没有复杂的帧头帧尾和转义规则就是裸字节流。CP1H做Modbus主站核心工作就四件事组帧、发帧、收帧、解帧。中间再插入一个轮询调度让多个读写任务有条不紊地跑。1.3 为什么不直接买通讯模块可能有人问既然台达和欧姆龙都有针对性的通讯方案为什么不直接买现成的网关或者模块原因很现实成本只是一方面更重要的是现场维护的透明性。自由口方案的报文是自己在程序里组装的变频器回的数据也是自己解析的。一旦现场通讯异常看一下程序里的收发缓冲区一眼就知道报文死在哪个环节是没发出去还是发了变频器没回还是回了但CRC不对。而用现成的通讯模块报文被封装在模块内部出了问题只能拿串口助手下到线上去抓包反而多一道工序。对熟悉梯形图的工程师来说自由口方案的调试难度不高只要把协议解析清楚剩下的工作量其实不大。另外CP1H本身留了内置串口和扩展通信板两种方式不需要额外增加太多硬件成本。2. 硬件接线与变频器侧参数配置2.1 CP1H串口扩展方案对比CP1H做自由口通讯常见的硬件接法有三种我直接按推荐顺序排方案硬件组成优点缺点推荐方案CP1H CP1W-CIF11 RS-485通信板稳定、RS485电平直接引出、端子接线方便需要占用扩展槽增加一块板卡成本常规方案CP1H内置RS232C口 RS232转RS485转换器不需要扩展板成本最低转换器质量参差不齐高速通讯容易丢数据较少用CP1W-CIF01/CIF02 转接电缆适合原有老设备改造灵活性差现在基本不推荐CP1W-CIF11是插在CP1H主机上的RS-485通信板插上之后相当于给PLC扩展了一个标准RS485串口。对于要和变频器组网通讯的场景我通常优先选它直接端子对端子接线比RS232转485中间加转换器干净得多。顺带说明一点CP1H内置的RS232C口做自由口通讯是可以的但RS232是点对点、电压型信号距离和抗干扰都比RS485差。变频器现场多的是强电干扰能用RS485就尽量不用RS232。2.2 RS485接线细节RS485是两线制半双工通讯CP1W-CIF11上一般会有S和S-两个接线端子。对应的台达VFD-M的通讯端子上通常也是两组标识常见的是S、S-部分机型标成D、D-个别版本还带一个SG端子作为信号地。接线要注意这几件事极性不能反。S接SS-接S-一旦反了变频器收不到任何数据但绝大多数情况下不会烧设备只是通讯不上。SG信号地建议连接。把两边的SG或者0V连在一起可以降低共模干扰导致的通讯误码。但注意这是信号地不要跟变频器的主回路地混在一起。通讯线用屏蔽双绞线。变频器输出侧就是强干扰源普通平行线走一两米问题不大走远了高频干扰会让你抓狂。屏蔽层单端接地。屏蔽层只在PLC侧或者只在变频器侧接地不要两头都接避免形成地环路电流。终端电阻。RS485总线两端各接一个120欧姆终端电阻。CP1W-CIF11上一般有跳线或者拨码可以启用终端电阻VFD-M可以查一下手册看有没有内置终端电阻选项。实际距离在10米以内、只有两台设备时终端电阻可以先不接超过20米或者有干扰症状就接上。2.3 台达VFD-M关键的参数设置变频器的通讯参数没有设置对程序写得再好也是白搭。VFD-M的通讯相关参数重点看这几个参数号名称推荐值说明00-01通讯地址1从站地址范围1~254PLC发报文时用同一个地址00-02通讯速率19600bpsPLC侧串口必须一致00-03通讯协议0或1务必选Modbus RTU不要选ASCII00-04通讯数据格式3或58-E-1或8-N-2PLC侧必须一致01-00主频率指令来源22代表RS485通讯给定频率01-01运转信号来源22代表RS485通讯给定启停命令这里一定要多说一句很多新手把通讯线接好了用Modbus调试工具发报文变频器能正常响应可PLC程序一跑却发现控制不了——原因就是变频器的频率指令来源和运转信号来源没有切换到“通讯”。如果这两个参数还是面板或端子给定的状态PLC发再多的正转命令变频器也只会按照自己的频率来源执行。另外修改变频器通讯参数之后有些机型需要断电重新上电才完全生效尤其是数据格式和协议相关的参数。参数改完最好断电重启一次别在调试时反复怀疑是自己的程序有问题。2.4 串口参数一致性检查表CP1H侧和VFD-M侧串口参数必须完全一致否则会出现“报文发出来了变频器回了一堆乱码”或者“变频器直接不理你”的情况。对照表如下参数PLC侧CX-Programmer串口设置变频器侧VFD-M参数波特率960000-021数据位800-04对应8位校验位无校验或偶校验00-04对应停止位1位或2位00-04对应从站地址报文首字节0100-011一个常见的坑默认情况下PLC侧的串口如果设置了无协议模式某些手册会默认“8位数据、无校验、2停止位”而变频器默认是“8-N-2”两边一凑往往就通了。但如果你把PLC侧改成了偶校验变频器那边就必须同步改成偶校验漏改一个字节都会导致整个通讯失败。3. Modbus报文与CRC校验先把协议吃透再写程序3.1 Modbus RTU帧结构Modbus RTU的帧结构非常规整发送和接收都是这样排布的从站地址(1字节) 功能码(1字节) 数据(N字节) CRC16(2字节, 低字节在前)其中CRC16占2个字节在报文里是低字节在前、高字节在后。这一点特别容易搞反搞反的结果就是变频器收到报文后校验不通过直接丢弃表现为“变频器毫无反应”。帧与帧之间至少要有3.5个字符时间的间隔。Modbus协议规定这个时间是为了让设备区分两帧数据的分界。PLC程序里如果两个命令之间延时太短变频器可能把两帧当成一帧数据这种情况在现场调试时很常见报文是对的、CRC也是对的但就是偶发无响应多半就是帧间隔不够。3.2 VFD-M寄存器地址对照台达VFD-M的Modbus寄存器地址常用的是这几个寄存器地址方向含义单位2000H写运行命令bit控制2001H写频率指令0.01Hz2100H读变频器状态bit状态2101H读输出频率0.01Hz2102H读输出电流0.01A2000H运行命令的位定义不同批次的产品略有差异最常见的是bit0 1正转运行bit1 1反转运行bit2 1停止所以在程序里我习惯写成正转命令发送2000H0001H反转命令发送2000H0002H停止命令发送2000H0004H。这三条命令分开处理逻辑非常清晰。3.3 CRC16计算方法与ST实现前面说了Modbus RTU的CRC有两种算法风格一种叫“查表法”运算速度快但需要一张256个字的表适合在上位机或者单片机里用另一种叫“移位法”代码简单、占资源少适合PLC的ST语言或功能块实现。CP1H的运算速度足够快移位法完全够用。CRC计算的规则是初始值取FFFFH每一个字节先跟当前CRC值做异或然后右移一位如果移出的位是1则异或A001H如此循环8次处理完所有字节后得到最终CRC值我用ST语言写过一个通用计算功能块CP1H的CX-Programmer支持ST写起来很顺手FUNCTION_BLOCK FB_CRC16 VAR_INPUT Data : ARRAY [0..15] OF WORD; // 待计算数据只用每个字的低字节 Len : WORD; // 字节数 END_VAR VAR_OUTPUT Result : WORD; // CRC计算结果 END_VAR VAR i : WORD; j : WORD; crc : WORD; END_VAR crc : 16#FFFF; FOR i : 0 TO Len - 1 DO crc : crc XOR (Data[i] AND 16#00FF); FOR j : 1 TO 8 DO IF (crc AND 1) 1 THEN crc : (crc SHR 1) XOR 16#A001; ELSE crc : crc SHR 1; END_IF; END_FOR; END_FOR; Result : crc;这个功能块接收一个“以字为单位”的数组每个元素的低字节就是报文里要发送的字节高字节忽略。算完之后Result的低字节是CRC低字节Result的高字节是CRC高字节。往发送缓冲区里放的时候记得低字节放前面。3.4 报文实例拆解拿一个最常用的操作举例把频率设定为50.00Hz从站地址是1寄存器2001H功能码06写单个保持寄存器。50.00Hz换算成寄存器值就是5000十六进制是1388H。那整帧报文就是01 06 20 01 13 88 CRClow CRChigh逐个字节解释01从站地址06写单个保持寄存器功能码20 01寄存器地址2001H高字节在前13 88要写入的数据高字节在前CRClow CRChigh前面6个字节的CRC校验再举一个读的例子读变频器的输出频率寄存器2101H功能码03。发送帧是01 03 21 01 00 01 CRClow CRChigh其中00 01表示读取1个寄存器。变频器正常响应时返回的帧是01 03 02 13 88 CRClow CRChigh解析一下01是从站地址回显03是功能码回显02表示后面跟了2个字节的数据13 88就是频率值5000也就是50.00Hz。实际调试时我会先用电脑上的串口调试工具把这两个报文发给变频器确认变频器能正确响应再回头写PLC程序。这一步可以帮你把“PLC程序问题”和“接线参数问题”彻底分开。4. CP1H自由口程序框架与梯形图实现4.1 数据区规划写程序前先把数据区规划好能省掉后面大量麻烦。我的习惯是这样分地址用途D100~D107发送缓冲区TXD直接从这里取数D200~D206接收缓冲区RXD收进来的数据放这里D300轮询步号0~3D301当前步重发计数D302连续通讯失败计数D500变频器运行状态字D501输出频率0.01HzD502输出电流0.01AW0.00启动轮询触发位W0.01发送请求标志W0.02接收完成处理标志W0.03通讯超时标志注意一点欧姆龙的TXD指令发送时是把发送缓冲区里每个通道的低字节依次发出去。所以组包时每个报文字节要放在对应的通道低字节。例如要发01 06 20 01 13 88那就是D100的低字节01D101的低字节06D102的低字节20D103的低字节01D104的低字节13D105的低字节88D106的低字节CRC低D107的低字节CRC高。4.2 无协议通讯的串口设置在CX-Programmer里打开“PLC设定”找到串口设置把通讯模式改为“无协议”。这里有两个关键项起始码和结束码都设为0000不启用。Modbus RTU不需要起始码和结束码帧长由字节数和间隔决定。接收格式要单独设置。CP1H无协议模式支持两种接收格式每一种可以指定固定的接收字节数。因为VFD-M的读响应是7字节地址功能码字节数2数据2CRC写响应是8字节地址功能码2地址2数据2CRC所以可以把接收格式1的字节数设为7接收格式2的字节数设为8。这样设置的好处是变频器回7字节时接收格式1的完成标志置ON回8字节时接收格式2的完成标志置ON。PLC侧不需要自己猜接收了多少字节。接收完成标志对应关系再啰嗦一遍内置RS232C口接收格式1完成标志A3.00接收格式2完成标志A3.01扩展通信板CP1W-CIF11接收格式1完成标志A3.02接收格式2完成标志A3.03我的主方案用的是CP1W-CIF11所以下面程序里的完成标志都按A3.02和A3.03来写。4.3 发送环节TXD指令与组包TXD指令的用法是这样的TXD 源首通道, 控制字, 字节数源首通道发送缓冲区起始地址例如D100控制字#0100 表示从扩展通信板端口发送、从源首通道的低字节开始取数。如果用的是内置RS232C口控制字改成#0000字节数8 或 7取决于当次发送的报文长度我习惯写一个“当前步报文组装”的子程序。比如D3000时组写运行命令帧D3001时组写频率指令帧D3002时组读状态帧D3003时组读频率帧。组包的具体操作就是把每个字节MOV到对应通道的低字节再调用CRC功能块算出CRC填入末尾两个通道。以D3001写频率50.00Hz为例梯形图里做这几步MOV 1 D100 → 从站地址MOV 6 D101 → 功能码06MOV 16#20 D102 → 寄存器地址高字节MOV 1 D103 → 寄存器地址低字节MOV 16#13 D104 → 数据高字节MOV 16#88 D105 → 数据低字节调用FB_CRC16输入D100、长度6得到结果存入D107高字节和D106低字节置W0.01为ON申请发送发送时W0.01上升沿触发TXD同时启动一个500ms的定时器作为超时判断。发送完成后要等待接收不要在这个时间段里再次触发TXD。4.4 接收环节RXD指令与帧解析RXD指令的用法和TXD对称RXD 接收首通道, 控制字, 字节数接收完成标志一旦ON就执行RXD把数据读走。以接收格式17字节为例如果A3.02是ON就执行RXD D200, #0100, 7数据读进D200~D206之后开始解帧先看D200低字节是否等于01从站地址不对就丢弃。再看D201低字节是否等于03读响应功能码不对就丢弃。然后对D200~D206这7个字节重新算一次CRC跟D205低字节CRC低和D206低字节CRC高比较不一致说明数据在传输中损坏丢弃。全部通过后把D203低字节数据高和D204低字节数据低组合成一个16位数据存入D501。梯形图里做这个组合我会用逻辑运算实现先把D203的低字节取出逻辑左移8位得到高字节部分再把D204的低字节取出作为低字节部分两者相或得到完整的16位寄存器值如果是接收格式2写响应8字节A3.03为ON执行RXD读回D200~D207。写响应的解析相对简单只要校验从站地址、功能码和CRC确认和发送帧一致即可不需要提取数据。4.5 轮询状态机的设计整个自由口通讯程序的核心是一个简单的轮询状态机。我习惯用D300做步号0到3循环步0发正转运行命令步1发频率设定命令50.00Hz步2读变频器状态步3读输出频率每步的执行流程都一样判断不是忙状态接收完成标志和超时标志都是OFF组帧置发送请求位TXD发送启动超时定时器等待两个事件之一接收完成标志ONRXD接收 → 解析 → 正确则D3001到4回0清零重发计数超时定时器ON重发计数1未超过3次则重新发送当前步超过3次则置通讯故障标志D3001继续跑下一轮不让整条程序卡死超时重发这个小设计非常重要。变频器偶尔会因为电网上电瞬间、母线电压建立等原因晚回一两拍直接判故障会让整个设备连环跳机。给它3次重试机会绝大多数偶发问题就自己过去了。如果连续三轮都失败那一定是硬件或参数有问题置故障让上位机提示比程序自己死磕靠谱。5. 常见问题与排查实录5.1 变频器完全没反应这是占比最高的问题。排查顺序我一般是这样的先确认PLC程序里的报文发出来了。拿一个USB转RS485模块接到总线上用串口调试工具监听。如果能看到CP1H发的报文说明TXD工作正常接下来看变频器有没有回。如果监听不到说明PLC侧串口配置或TXD控制字有问题。确认变频器参数生效。尤其是数据格式、协议、地址改完有没有断电重启。这一点我每次都要强调现场很多人改完参数直接按“确认”就测通讯协议和数据格式有时不能即时生效。确认RS485接线极性。S和S-接反是最常见的低级故障几乎每个人都会遇到一次。确认PLC侧和变频器侧波特率、停止位一致。排查时建议做一个“最小闭环测试”只发一条读2101H的报文03功能码、命令最安全不会改变变频器状态如果变频器能正常回说明整条链路是通的。5.2 数据能读但控制无效报文能收能发读频率、读电流都有数据但PLC发运行命令变频器就是不动。这种问题九成出在变频器的控制指令来源没切到通讯模式。比如一台VFD-M频率来源01-002、运转信号来源01-012外部端子没有给使能信号通讯命令也会被屏蔽。还有一部分机型有“外部端子控制优先”逻辑需要把外部端子使能回路短接或者放开。另一个隐蔽问题2000H命令字里的停止位可能和你发的内容冲突。比如你发正转0001H但变频器内部要求bit2停止位必须为0如果程序里上一次停止命令还把bit2置1那这一次的正转命令就会被覆盖。所以我的习惯是正转、反转、停止三条命令使用独立的赋值逻辑正转时强制写0001H不要叠加其他位。5.3 CRC与乱码问题收下来的报文能看但CRC校验不过通常有三种原因组帧时字节序错了寄存器地址和数据都是高字节在前写反了变频器要么不响应要么回异常码。CRC高低字节放反了Modbus要求低字节在前放反之后变频器校验永远失败。接收长度不对RXD的接收字节数和实际响应长度不一致会把后面的字节截掉或粘帧。还有一个容易忽略的点CP1H的TXD发送的是通道低字节如果你组帧时把字节放到了高字节TXD仍然会把低字节发出去导致报文完全不是你想象的内容。组完帧之后用串口助手下线看一下实际发出的字节序列比在梯形图里反复核对高效得多。5.4 现场抗干扰问题变频器一启动通讯就断变频器一停通讯就恢复。这是很典型的RS485干扰现场。对应措施通讯线改成屏蔽双绞线屏蔽层单端接地通讯线远离变频器输出线和动力电缆不要并行走线两台设备距离超过20米时在两端接上120欧姆终端电阻把波特率从19200降到9600有时候就能稳住如果有偏置电阻设置在无数据时让总线保持一个确定电平可以避免空闲时段收到杂波我在一个现场遇到过必须把波特率降到4800才稳定的情况原因是走线跟变频器输出线困在同一个线槽里。最后重新拉了一根屏蔽线9600就恢复正常了。布线影响比协议还大别忽视。5.5 调试工具与调试顺序调试这套自由口通讯我强烈建议按这个顺序来能省一半以上的时间先用电脑串口调试工具USB转RS485直连变频器。直接把读频率、写频率、正转、停止这几条报文发给变频器确认变频器本身是好的、寄存器地址是正确的、参数是生效的。再用CP1H自发自收。把TXD的发送目标先指向一个空口或者把回显接回自己的接收端确认TXD和RXD指令、控制字、接收格式配置都能正常工作。最后接上变频器跑联合调试。到了这一步如果再有问题多半就是接线极性、干扰或者参数不一致了。整个调试过程中我习惯在手边放一张“报文速查卡”上面写好几条常用报文读频率、读电流、正转、反转、停止、写50Hz。逐条验证效率极高。你用不着把Modbus协议背得滚瓜烂熟但一定要会拼一条正确的报文并且知道CRC算出来应该放在哪个位置。这套自由口通讯方案跑起来之后其实稳定性比很多人想象的要好。原因也简单报文是自己组的、CRC是自己算的、时序是自己控的每一步都看得见摸得着。真出现一个异常程序里D302的失败计数会明确告诉你是哪一步出了问题不用拿万用表去猜。我个人体会最深的一点是CP1H和VFD-M通讯这件事最大的门槛不在PLC指令也不在变频器参数而在你是否愿意把报文的每个字节、每个字节序、每个校验位都理解到位。把这套自由口的思路吃透之后你会发现以后接温控器、接仪表、接伺服驱动器全都是一样的套路换张寄存器表就能复用。
阅读完成 · 觉得有帮助?