-
Notifications
You must be signed in to change notification settings - Fork 0
/
ModbusRtu.h
executable file
·195 lines (181 loc) · 6.52 KB
/
ModbusRtu.h
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
/**
* @file ModbusRtu.h
* @version 1.21
* @date 2016.02.21
* @author Samuel Marco i Armengol
* @contact sammarcoarmengol@gmail.com
* @contribution Helium6072
* @contribution gabrielsan
*
* @description
* Arduino library for communicating with Modbus devices
* over RS232/USB/485 via RTU protocol.
*
* Further information:
* http://modbus.org/
* http://modbus.org/docs/Modbus_over_serial_line_V1_02.pdf
*
* @license
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; version
* 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* @defgroup setup Modbus Object Instantiation/Initialization
* @defgroup loop Modbus Object Management
* @defgroup buffer Modbus Buffer Management
* @defgroup discrete Modbus Function Codes for Discrete Coils/Inputs
* @defgroup register Modbus Function Codes for Holding/Input Registers
*
*/
#include "project.h"
//#include <inttypes.h>
//#include <CyLib.h>
#define HIGH 0x1
#define LOW 0x0
#define INPUT 0x0
#define OUTPUT 0x1
#define true 0x1
#define false 0x0
#define LSBFIRST 0
#define MSBFIRST 1
#define CHANGE 1
#define FALLING 2
#define RISING 3
#define INTERNAL 3
#define DEFAULT 1
#define EXTERNAL 0
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define lowByte(w) ((uint8_t) ((w) & 0xff))
#define highByte(w) ((uint8_t) ((w) >> 8))
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
/**
* @struct modbus_t
* @brief
* Master query structure:
* This includes all the necessary fields to make the Master generate a Modbus query.
* A Master may keep several of these structures and send them cyclically or
* use them according to program needs.
*/
typedef struct
{
uint8_t u8id; /*!< Slave address between 1 and 247. 0 means broadcast */
uint8_t u8fct; /*!< Function code: 1, 2, 3, 4, 5, 6, 15 or 16 */
uint16_t u16RegAdd; /*!< Address of the first register to access at slave/s */
uint16_t u16CoilsNo; /*!< Number of coils or registers to access */
uint16_t *au16reg; /*!< Pointer to memory image in master */
}
modbus_t;
enum
{
RESPONSE_SIZE = 6,
EXCEPTION_SIZE = 3,
CHECKSUM_SIZE = 2
};
/**
* @enum MESSAGE
* @brief
* Indexes to telegram frame positions
*/
enum MESSAGE
{
ID = 0, //!< ID field
FUNC, //!< Function code position
ADD_HI, //!< Address high byte
ADD_LO, //!< Address low byte
NB_HI, //!< Number of coils or registers high byte
NB_LO, //!< Number of coils or registers low byte
BYTE_CNT //!< byte counter
};
/**
* @enum MB_FC
* @brief
* Modbus function codes summary.
* These are the implement function codes either for Master or for Slave.
*
* @see also fctsupported
* @see also modbus_t
*/
enum MB_FC
{
MB_FC_NONE = 0, /*!< null operator */
MB_FC_READ_COILS = 1, /*!< FCT=1 -> read coils or digital outputs */
MB_FC_READ_DISCRETE_INPUT = 2, /*!< FCT=2 -> read digital inputs */
MB_FC_READ_REGISTERS = 3, /*!< FCT=3 -> read registers or analog outputs */
MB_FC_READ_INPUT_REGISTER = 4, /*!< FCT=4 -> read analog inputs */
MB_FC_WRITE_COIL = 5, /*!< FCT=5 -> write single coil or output */
MB_FC_WRITE_REGISTER = 6, /*!< FCT=6 -> write single register */
MB_FC_WRITE_MULTIPLE_COILS = 15, /*!< FCT=15 -> write multiple coils or outputs */
MB_FC_WRITE_MULTIPLE_REGISTERS = 16 /*!< FCT=16 -> write multiple registers */
};
enum COM_STATES
{
COM_IDLE = 0,
COM_WAITING = 1
};
enum ERR_LIST
{
ERR_NOT_MASTER = -1,
ERR_POLLING = -2,
ERR_BUFF_OVERFLOW = -3,
ERR_BAD_CRC = -4,
ERR_EXCEPTION = -5
};
enum
{
NO_REPLY = 255,
EXC_FUNC_CODE = 1,
EXC_ADDR_RANGE = 2,
EXC_REGS_QUANT = 3,
EXC_EXECUTE = 4
};
#define T35 5
#define MAX_BUFFER 254 //!< maximum size for the communication buffer in bytes
/**
* @class Modbus
* @brief
* Arduino class library for communicating with Modbus devices over
* USB/RS232/485 (via RTU protocol).
*/
void Modbus_init();
void Modbus_sendTxBuffer();
int8_t Modbus_getRxBuffer();
uint16_t Modbus_calcCRC(uint8_t u8length);
uint8_t Modbus_validateAnswer();
uint8_t Modbus_validateRequest();
void Modbus_get_FC1();
void Modbus_get_FC3();
int8_t Modbus_process_FC1( uint16_t *regs);
int8_t Modbus_process_FC3( uint16_t *regs);
int8_t Modbus_process_FC6( uint16_t *regs);
int8_t Modbus_process_FC15( uint16_t *regs);
int8_t Modbus_process_FC16( uint16_t *regs);
void Modbus_buildException( uint8_t u8exception ); // build exception message
void Modbus_begin();
void Modbus_setTimeOut( uint16_t u16timeOut); //!<write communication watch-dog timer
uint16_t Modbus_getTimeOut(); //!<get communication watch-dog timer value
_Bool Modbus_getTimeOutState(); //!<get communication watch-dog timer state
int8_t Modbus_query( modbus_t telegram ); //!<only for master
int8_t Modbus_poll(); //!<cyclic poll for master
uint16_t Modbus_getInCnt(); //!<number of incoming messages
uint16_t Modbus_getOutCnt(); //!<number of outcoming messages
uint16_t Modbus_getErrCnt(); //!<error counter
uint8_t Modbus_getID(); //!<get slave ID between 1 and 247
uint8_t Modbus_getState();
uint8_t Modbus_getLastError(); //!<get last error message
void Modbus_setTxendPinOverTime( uint32_t u32overTime );
void Modbus_end(); //!<finish any communication and release serial communication port