
Modbus是一种串行通信协议,是Modicon公司(现在的施耐德电气SchneiderElectric)于1979年为使用可编程逻辑控制器(PLC)通信而发表。Modbus已经成为工业领域通信协议的......
Modbus是一种串行通信协议,是Modicon公司(现在的施耐德电气SchneiderElectric)于1979年为使用可编程逻辑控制器(PLC)通信而发表。Modbus已经成为工业领域通信协议的业界标准(Defacto),并且现在是工业电子设备之间常用的连接方式。
Modbus协议目前存在用于串口、以太网以及其他支持互联网协议的网络的版本。
其中ModbusRTU通信通过串口EIA-485物理层进行。即ModbusRTU基于485传输方式进行。若设备只有一个232串口接口,也可购买485转232接口后使用。
本文介绍ABB机器人使用ModbusRTU与设备进行通讯。ABB机器人使用串口通讯不需要选项。
1.ABB机器人控制柜提供com1口作为机器人与外部设备通讯的串口,如下图。若使用ModbusRTU通讯,需要购买485转223接口。机器人侧用232,在使用串口线时注意交叉接线。

在示教器的控制面板-配置-主题communication-SerialPort中,根据ModbusRTU主站设备的要求,设置机器人串口参数

2.Modbusrtu通过不同功能码对相应单个线圈/多个寄存器进行读写,例如使用0x03功能码读取多个保持型寄存器数据,发送数据及返回数据格式如下:

使用0x10功能码写入多个保持型寄存器数据,发送数据及返回数据格式如下:

3.其他功能码如下:

4.使用ModbusRTU进行数据读写时,从站需要发送CRC校验码,CRC校验内容为CRC校验码之前的所有数据,ModbusRTUCRC校验码计算方法如下:
在CRC计算时只用8个数据位,起始位及停止位,如有奇偶校验位也包括奇偶校验位,都不参与CRC计算。
1、加载一值为0XFFFF的16位寄存器,此寄存器为CRC寄存器。2、把第一个8位二进制数据(即通讯信息帧的第一个字节)与16位的CRC寄存器的相异或,异或的结果仍存放于该CRC寄存器中。3、把CRC寄存器的内容右移一位,用0填补最高位,并检测移出位是0还是1。4、如果移出位为零,则重复第三步(再次右移一位);如果移出位为1,CRC寄存器与0XA001进行异或。5、重复步骤3和4,直到右移8次,这样整个8位数据全部进行了处理。6、重复步骤2和5,进行通讯信息帧下一个字节的处理。7、将该通讯信息帧所有字节按上述步骤计算完成后,得到的16位CRC寄存器的高、低字节进行交换8、最后得到的CRC寄存器内容即为:CRC校验码
具体代码如下:
FUNCuShortfGetCRC16(bytearr{*},numlength)VARdnumcrc;VARnumlen;VARuShortCRC16;crc:=65535;len:=1;WHILElen=lengthDOcrc:=BitXOrDnum(crc,NumToDnum(arr{len}));incrlen;FORiFROM1TO8DOIFBitAndDnum(crc,0x01)=1THENcrc:=BitXOrDnum(BitRShDnum(crc,1),0xa001);ELSEcrc:=BitRShDnum(crc,1);:=DnumToNum(BitAndDnum(crc,0xff));:=DnumToNum(BitRShDnum(BitAndDnum(crc,0xff00),8));RETURNCRC16;ENDFUNC5.以下举例通过ABB机器人对汇川sp600伺服基于ModbusRTU写入地址H31-00,bit0为1的数据,对伺服Enable
PROCInnoEnable()rModbusWriteInnoID,[0x31,0x00],[0,1];!设备地址InnoID为1,写入数据地址为H31-00,写入数据为1ENDPROCPROCrModbusWrite(byteslaveID,ushortopAdd,ushortData)VARuShortcrc;VARuShortres;VARbytesArr{8};sArr{1}:=slaveID;sArr{2}:=0x06;!功能码0x06,写入一个寄存器sArr{3}:=;sArr{4}:=;sArr{5}:=;sArr{6}:=;crc:=fGetCRC16(sArr,6);sArr{7}:=;sArr{8}:=;rSerialWritesArr,8;;ENDPROCPROCrSerialWrite(bytearray{*},numlen)ClearRawBytesraw_data_out;FORiFROM1TOlenDOPackRawBytesarray{i},raw_data_out,RawBytesLen(raw_data_out)+1\Hex1;ENDFOROpen"COM1",io_device\Bin;ClearIOBuffio_device;WriteRawBytesio_device,raw_data_out;Closeio_device;UNDOCloseio_device;ENDPROC6.以下举例通过ABB机器人对汇川sp600伺服基于modbusrtu读取地址H0B-00的数据,获取伺服电机转速(返回数据为16bit的INT数据)
FUNCnumInnoReadSpeed()VARnumresult;VARuShortcrc;VARbytesArr{8};VARbyteresultArr{8};VARrawbytesrawbyte1;sArr{1}:=InnoID;sArr{2}:=0x04;!readinputregisteruse0x04sArr{3}:=0x0B;sArr{4}:=0x00;!参数地址H0B-00sArr{5}:=0X00;sArr{6}:=0X01;!读取个数1crc:=fGetCRC16(sArr,6);sArr{7}:=;sArr{8}:=;rSerialWritesArr,8;rSerialReadresultArr,7;crc:=fGetCRC16(resultArr,5);{7}{6}THENErrWrite"CRC16-ERROR","";Stop;EXIT;ENDIFPackRawBytesresultArr{5},rawbyte1,1\Hex1;PackRawBytesresultArr{4},rawbyte1,2\Hex1;UnpackRawBytesrawbyte1,1,result\IntX:=INT;!返回数据为16bit的有符号INT数据,按照INT数据进行RETURNresult;ENDFUNCPROCrSerialRead(inoutbytearray{*},numrLength)VARnumnum1;ClearRawBytesraw_data_in;Open"COM1",io_device\Bin;Rewindio_device;FORiFROM1TOrLengthDOnum1:=ReadBin(io_device\Time:=0.5);array{i}:=num1;ENDFORClearIOBuffio_device;Closeio_device;UNDOCloseio_device;ENDPROC