DELL
2025-01-08 2b4592b9be195945169718aac36cf51f6ce9f894
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
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 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);
    }
    
}