package com.dev.modbus; import java.nio.ByteBuffer; import java.nio.ByteOrder; import com.base.ComBase; import com.base.Crc16; public class MyModBusRtu { public static final int BYTE_LEN = 7; public static final short CMD_TYPE_READ = 0x03; //读保持寄存器 public static final short CMD_TYPE_READ_INPUT = 0x04; //读输入寄存器 public static final short CMD_TYPE_WRITE_YC = 0x05; public static final short CMD_TYPE_WRITE_STD = 0x06; //单点写入 public static final short CMD_TYPE_WRITE_MULTY = 0x10; //多点写入 public int addr = 0xFF; //设备地址 public int Cmd; //功能码 public int reg_addr; //寄存器地址 public int reg_count; //寄存器数量 public int data_count; //数据区字节数量 public int result; //返回操作结果 public int crc; //crc校验 public int write_value; //单点写入时的数值 public MyModBusRtu() { } public MyModBusRtu(int Cmd,int reg_addr) { this.Cmd = Cmd; this.reg_addr = reg_addr; } public MyModBusRtu(int addr) { this.addr = addr; } public void mkBusRtu(int Cmd,int reg_addr) { this.Cmd = Cmd; this.reg_addr = reg_addr; } public void mkBusRtu(int Cmd,int reg_addr,int reg_count) { this.Cmd = Cmd; this.reg_addr = reg_addr; this.reg_count = reg_count; } public void mkBusRtu(int addr,int Cmd,int reg_addr,int reg_count) { this.addr = addr; this.Cmd = Cmd; this.reg_addr = reg_addr; this.reg_count = reg_count; } public void clear() { this.addr = 0; //设备地址 this.Cmd = 0; //功能码 this.reg_addr = 0; //寄存器地址 this.reg_count = 0; //寄存器数量 this.data_count = 0; //数据区字节数量 this.result = 0; //返回操作结果 } /** * 构造基础发送数据 * @return */ public ByteBuffer mkByteBuffer() { ByteBuffer bytebuffer = ByteBuffer.allocate(BYTE_LEN); bytebuffer.order(ByteOrder.BIG_ENDIAN); bytebuffer.position(0); bytebuffer.put(ComBase.changeIntToByte(addr)); bytebuffer.put(ComBase.changeIntToByte(Cmd)); bytebuffer.putShort(ComBase.changeIntToShort(reg_addr)); if(CMD_TYPE_WRITE_STD == Cmd || CMD_TYPE_WRITE_YC == Cmd) { }else if(CMD_TYPE_WRITE_MULTY == Cmd) { //多点写入时,每个寄存器4个字节 bytebuffer.putShort(ComBase.changeIntToShort(reg_count)); bytebuffer.put(ComBase.changeIntToByte(reg_count*4)); } else { bytebuffer.putShort(ComBase.changeIntToShort(reg_count)); } bytebuffer.flip(); return bytebuffer; } public boolean putByteBuffer(final ByteBuffer bf) { if(bf.limit() < BYTE_LEN) return false; ByteBuffer tmpbuf = bf; int crc0 = tmpbuf.getShort(bf.limit()-2) & 0xFFFF; int crc1 = Crc16.CalCRC16(tmpbuf, bf.limit()-2) & 0xFFFF; if(crc0 != crc1) { System.err.println("CRC error "+crc0+"==="+crc1); return false; } tmpbuf.position(0); this.addr = tmpbuf.get()&0xFF; //设备地址 this.Cmd = tmpbuf.get()&0xFF; //功能码 if(CMD_TYPE_READ == this.Cmd) { this.data_count = tmpbuf.getShort()&0xFFFF; }else if(CMD_TYPE_READ_INPUT == this.Cmd){ this.data_count = tmpbuf.get()&0xFF; }else if(CMD_TYPE_WRITE_STD == this.Cmd || CMD_TYPE_WRITE_YC == this.Cmd || CMD_TYPE_WRITE_MULTY == this.Cmd){ //设置时的返回结果 this.reg_addr = tmpbuf.getShort()&0xFFFF; //寄存器地址 this.result = tmpbuf.getShort()&0xFFFF; } tmpbuf.compact(); tmpbuf.flip(); return true; } public static void main(String[] args) { byte[] data = new byte[] {(byte) 0xa0 ,(byte)0xdd,0x6c ,0x23,0x26,0x16}; ByteBuffer bf = ByteBuffer.allocate(data.length); bf.order(ByteOrder.BIG_ENDIAN); bf.put(data); System.out.println(Crc16.CalCRC16(bf, bf.limit())&0xFFFF); System.out.println(Crc16.CalCRC16(data, bf.limit())&0xFFFF); } }