Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
T
Thick-Common
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
潘栩锋
Thick-Common
Commits
156b8a7b
Commit
156b8a7b
authored
Jun 12, 2024
by
潘栩锋
🚴
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
添加 ModbusServer 支持 04功能包
parent
8e26f37f
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
220 additions
and
8 deletions
+220
-8
ModbusAsciiServer.cs
GeneralGommunication/ModbusAsciiServer.cs
+105
-5
ModbusRtuServer.cs
GeneralGommunication/ModbusRtuServer.cs
+112
-2
ModbusServer.cs
GeneralGommunication/ModbusServer.cs
+3
-1
No files found.
GeneralGommunication/ModbusAsciiServer.cs
View file @
156b8a7b
...
@@ -24,7 +24,8 @@ namespace GeneralGommunication
...
@@ -24,7 +24,8 @@ namespace GeneralGommunication
MBA_STATUS_0A
=
2
MBA_STATUS_0A
=
2
}
}
ModbusAsciiStatus
status
;
ModbusAsciiStatus
status
;
ModbusRegReadWriteHandler
regRead
;
ModbusRegReadWriteHandler
regRead_Holding
;
ModbusRegReadWriteHandler
regRead_Input
;
ModbusRegReadWriteHandler
regWrite
;
ModbusRegReadWriteHandler
regWrite
;
Action
<
IEnumerable
<
byte
>>
sendMsg
;
Action
<
IEnumerable
<
byte
>>
sendMsg
;
...
@@ -34,10 +35,14 @@ namespace GeneralGommunication
...
@@ -34,10 +35,14 @@ namespace GeneralGommunication
//上一次接收数据的时间
//上一次接收数据的时间
DateTime
lastRecMsgTime
;
DateTime
lastRecMsgTime
;
public
void
Init
(
ModbusRegReadWriteHandler
regRead
,
ModbusRegReadWriteHandler
regWrite
,
public
void
Init
(
ModbusRegReadWriteHandler
regRead_Holding
,
ModbusRegReadWriteHandler
regRead_Input
,
ModbusRegReadWriteHandler
regWrite
,
Action
<
IEnumerable
<
byte
>>
sendMsg
,
out
Action
<
IEnumerable
<
byte
>>
recMsg
)
Action
<
IEnumerable
<
byte
>>
sendMsg
,
out
Action
<
IEnumerable
<
byte
>>
recMsg
)
{
{
this
.
regRead
=
regRead
;
this
.
regRead_Holding
=
regRead_Holding
;
this
.
regRead_Input
=
regRead_Input
;
this
.
regWrite
=
regWrite
;
this
.
regWrite
=
regWrite
;
this
.
sendMsg
=
sendMsg
;
this
.
sendMsg
=
sendMsg
;
recMsg
=
RecMsg
;
recMsg
=
RecMsg
;
...
@@ -54,7 +59,7 @@ namespace GeneralGommunication
...
@@ -54,7 +59,7 @@ namespace GeneralGommunication
/// <summary>
/// <summary>
/// Read REGs
/// Read
Holding
REGs
/// </summary>
/// </summary>
/// <param name="buf">传入通讯字元</param>
/// <param name="buf">传入通讯字元</param>
/// <param name="startIndex"></param>
/// <param name="startIndex"></param>
...
@@ -118,7 +123,12 @@ namespace GeneralGommunication
...
@@ -118,7 +123,12 @@ namespace GeneralGommunication
midBuf
.
Add
((
byte
)(
number
*
2
));
midBuf
.
Add
((
byte
)(
number
*
2
));
UInt16
[]
regValues
=
new
UInt16
[
number
];
UInt16
[]
regValues
=
new
UInt16
[
number
];
bool
ret
=
this
.
regRead
(
deviceNo
,
startAddr
,
regValues
);
if
(
this
.
regRead_Holding
==
null
)
{
//读取失败,没有设备,不用回复
return
;
}
bool
ret
=
this
.
regRead_Holding
(
deviceNo
,
startAddr
,
regValues
);
if
(!
ret
)
if
(!
ret
)
{
{
//读取失败,没有设备,不用回复
//读取失败,没有设备,不用回复
...
@@ -133,7 +143,90 @@ namespace GeneralGommunication
...
@@ -133,7 +143,90 @@ namespace GeneralGommunication
Modbus_AddLrcAndSend
(
midBuf
);
Modbus_AddLrcAndSend
(
midBuf
);
}
}
/// <summary>
/// Read Input REGs
/// </summary>
/// <param name="buf">传入通讯字元</param>
/// <param name="startIndex"></param>
/// <param name="len">buf长度</param>
void
Modbus_Func04
(
IEnumerable
<
byte
>
buf
,
int
startIndex
,
int
len
)
{
//请求
//0. ':' 0x3A
//1. slave address : 2bytes ascii
//2. Function : 2bytes ascii
//3. Starting Address Hi : 2bytes ascii
//4. Starting Address Lo : 2bytes ascii
//5. Number of Register Hi : 2bytes ascii
//6. Number of Register Lo : 2bytes ascii
//7. LRC : 2bytes ascii
//8. 0x0D 0x0A
//响应
//0. ':' 0x3A
//1. slave address : 2bytes ascii
//2. Function : 2bytes ascii
//3. Number * 2 : 2bytes ascii
//下面重复 Number 次
//4. Data Hi : 2bytes ascii
//5. Data Lo : 2bytes ascii
//6. LRC : 2bytes ascii
//7. 0x0D 0x0A
//example: 下面为 ASCII
//请求
//: 01 03 00 01 00 01 ?? (0X0D) (0X0A)
//响应
//: 01 03 02 12 34 ?? (0X0D) (0X0A)
//buf 已经是 ascii转hex 后结果。 从 slave address 开始,没有LRC
if
(
len
<
6
)
{
Modbus_DefaultCallback
(
buf
,
startIndex
,
MB_ERR_LEN
);
//指令异常
return
;
}
byte
deviceNo
=
buf
.
ElementAt
(
startIndex
);
UInt16
startAddr
=
buf
.
ToUInt16_Big_Endian
(
startIndex
+
2
);
UInt16
number
=
buf
.
ToUInt16_Big_Endian
(
startIndex
+
4
);
if
(
number
==
0
)
{
Modbus_DefaultCallback
(
buf
,
startIndex
,
MB_ERR_NUM_0
);
//指令异常
return
;
}
if
(
number
>
50
)
//限制数量,因为缓存区不够大
number
=
50
;
List
<
byte
>
midBuf
=
new
List
<
byte
>();
midBuf
.
Add
(
deviceNo
);
midBuf
.
Add
(
0x04
);
midBuf
.
Add
((
byte
)(
number
*
2
));
UInt16
[]
regValues
=
new
UInt16
[
number
];
if
(
this
.
regRead_Input
==
null
)
{
//读取失败,没有设备,不用回复
return
;
}
bool
ret
=
this
.
regRead_Input
(
deviceNo
,
startAddr
,
regValues
);
if
(!
ret
)
{
//读取失败,没有设备,不用回复
return
;
}
for
(
int
i
=
0
;
i
<
number
;
i
++)
{
midBuf
.
AddRange
(
regValues
[
i
].
GetBytes_Big_endian
());
}
Modbus_AddLrcAndSend
(
midBuf
);
}
/// <summary>
/// <summary>
/// Write Single REG
/// Write Single REG
/// </summary>
/// </summary>
...
@@ -183,6 +276,8 @@ namespace GeneralGommunication
...
@@ -183,6 +276,8 @@ namespace GeneralGommunication
UInt16
regValue
=
buf
.
ToUInt16_Big_Endian
(
startIndex
+
4
);
UInt16
regValue
=
buf
.
ToUInt16_Big_Endian
(
startIndex
+
4
);
UInt16
[]
regValues
=
new
UInt16
[]
{
regValue
};
UInt16
[]
regValues
=
new
UInt16
[]
{
regValue
};
if
(
this
.
regWrite
==
null
)
return
;
//写入失败,没有设备,不用回复
bool
ret
=
this
.
regWrite
(
deviceNo
,
startAddr
,
regValues
);
bool
ret
=
this
.
regWrite
(
deviceNo
,
startAddr
,
regValues
);
if
(!
ret
)
if
(!
ret
)
{
{
...
@@ -282,6 +377,8 @@ namespace GeneralGommunication
...
@@ -282,6 +377,8 @@ namespace GeneralGommunication
index
+=
2
;
index
+=
2
;
regValues
[
i
]
=
regValue
;
regValues
[
i
]
=
regValue
;
}
}
if
(
this
.
regWrite
==
null
)
return
;
//写入失败,没有设备,不用回复
bool
ret
=
this
.
regWrite
(
deviceNo
,
startAddr
,
regValues
);
bool
ret
=
this
.
regWrite
(
deviceNo
,
startAddr
,
regValues
);
if
(!
ret
)
if
(!
ret
)
...
@@ -470,6 +567,9 @@ namespace GeneralGommunication
...
@@ -470,6 +567,9 @@ namespace GeneralGommunication
case
0x03
:
case
0x03
:
Modbus_Func03
(
midBuf
,
0
,
adu_len
);
Modbus_Func03
(
midBuf
,
0
,
adu_len
);
break
;
break
;
case
0x04
:
Modbus_Func04
(
midBuf
,
0
,
adu_len
);
break
;
//case 0x05:
//case 0x05:
// Modbus_Func05(buf, adu_len);
// Modbus_Func05(buf, adu_len);
// break;
// break;
...
...
GeneralGommunication/ModbusRtuServer.cs
View file @
156b8a7b
...
@@ -19,7 +19,7 @@ namespace GeneralGommunication
...
@@ -19,7 +19,7 @@ namespace GeneralGommunication
const
byte
MB_ERR_CNT
=
0x03
;
//字节数!=寄存器数量*2
const
byte
MB_ERR_CNT
=
0x03
;
//字节数!=寄存器数量*2
const
byte
MB_ERR_NOFUNC
=
0x05
;
//没有这个func
const
byte
MB_ERR_NOFUNC
=
0x05
;
//没有这个func
ModbusRegReadWriteHandler
regRead_Input
;
ModbusRegReadWriteHandler
regRead
;
ModbusRegReadWriteHandler
regRead
;
ModbusRegReadWriteHandler
regWrite
;
ModbusRegReadWriteHandler
regWrite
;
Action
<
IEnumerable
<
byte
>>
sendMsg
;
Action
<
IEnumerable
<
byte
>>
sendMsg
;
...
@@ -30,10 +30,11 @@ namespace GeneralGommunication
...
@@ -30,10 +30,11 @@ namespace GeneralGommunication
System
.
Threading
.
Timer
timer3d5t
;
//通讯包的 3.5T 时间间隔。 实际只是 15ms定时而已
System
.
Threading
.
Timer
timer3d5t
;
//通讯包的 3.5T 时间间隔。 实际只是 15ms定时而已
public
void
Init
(
ModbusRegReadWriteHandler
regRead
,
ModbusRegReadWriteHandler
regWrite
,
public
void
Init
(
ModbusRegReadWriteHandler
regRead
,
ModbusRegReadWriteHandler
reg
Read_Input
,
ModbusRegReadWriteHandler
reg
Write
,
Action
<
IEnumerable
<
byte
>>
sendMsg
,
out
Action
<
IEnumerable
<
byte
>>
recMsg
)
Action
<
IEnumerable
<
byte
>>
sendMsg
,
out
Action
<
IEnumerable
<
byte
>>
recMsg
)
{
{
this
.
regRead
=
regRead
;
this
.
regRead
=
regRead
;
this
.
regRead_Input
=
regRead_Input
;
this
.
regWrite
=
regWrite
;
this
.
regWrite
=
regWrite
;
this
.
sendMsg
=
sendMsg
;
this
.
sendMsg
=
sendMsg
;
recMsg
=
RecMsg
;
recMsg
=
RecMsg
;
...
@@ -135,6 +136,13 @@ namespace GeneralGommunication
...
@@ -135,6 +136,13 @@ namespace GeneralGommunication
midBuf
.
Add
((
byte
)(
number
*
2
));
midBuf
.
Add
((
byte
)(
number
*
2
));
UInt16
[]
regValues
=
new
UInt16
[
number
];
UInt16
[]
regValues
=
new
UInt16
[
number
];
if
(
this
.
regRead
==
null
)
{
//读取失败,没有设备,不用回复
logger
.
Debug
(
$"REQ 读取失败,没有设置regRead,不用回复"
);
sendBuf
=
null
;
return
req_len
;
}
bool
ret
=
this
.
regRead
(
deviceNo
,
startAddr
,
regValues
);
bool
ret
=
this
.
regRead
(
deviceNo
,
startAddr
,
regValues
);
if
(!
ret
)
if
(!
ret
)
{
{
...
@@ -154,7 +162,109 @@ namespace GeneralGommunication
...
@@ -154,7 +162,109 @@ namespace GeneralGommunication
//Modbus_AddCrcAndSend(midBuf);
//Modbus_AddCrcAndSend(midBuf);
}
}
/// <summary>
/// 读寄存器, 返回已经处理的长度
/// </summary>
/// <param name="buf">接收缓冲</param>
/// <param name="startIndex">数据开始序号</param>
/// <param name="len">数据长度</param>
/// <returns></returns>
int
Modbus_Func04
(
IEnumerable
<
byte
>
buf
,
int
startIndex
,
int
len
,
out
byte
[]
sendBuf
)
{
//请求
//1. slave address : 1byte
//2. Function : 1byte
//3. Starting Address Hi : 1byte
//4. Starting Address Lo : 1byte
//5. Number of Register Hi : 1byte
//6. Number of Register Lo : 1byte
//7. CRC16 : 2bytes
//响应
//1. slave address : 1byte
//2. Function : 1byte
//3. Number * 2 : 1byte
//下面重复 Number 次
//4. Data Hi : 1byte
//5. Data Lo : 1byte
//6. CRC16 : 2bytes
//example:
//请求
//01 03 00 01 00 01 ?? ??
//响应
//01 03 02 12 34 ?? ??
int
req_len
=
8
;
//buf 从 slave address 开始
if
(
len
<
req_len
)
{
logger
.
Error
(
$"REQ 指令字节数不足"
);
sendBuf
=
Modbus_DefaultCallback
(
buf
,
startIndex
,
MB_ERR_LEN
);
//指令异常
return
len
;
}
//CRC
int
adu_len
=
req_len
-
2
;
//去除crc后的数据包长
UInt16
crc
=
buf
.
CRC16
(
startIndex
,
req_len
-
2
);
UInt16
rec_crc
=
buf
.
ToUInt16_Little_Endian
(
startIndex
+
req_len
-
2
);
//CRC 是 小端模式
if
(
crc
!=
rec_crc
)
{
logger
.
Error
(
$"REQ CRC 校验出错 接收:
{
rec_crc
:
X4
}
计算:
{
crc
:
X4
}
"
);
sendBuf
=
Modbus_DefaultCallback
(
buf
,
startIndex
,
MB_ERR_LRC
);
//指令异常
return
len
;
//指令异常,应该全部删除
}
byte
deviceNo
=
recBuf
[
0
];
UInt16
startAddr
=
buf
.
ToUInt16_Big_Endian
(
startIndex
+
2
);
UInt16
number
=
buf
.
ToUInt16_Big_Endian
(
startIndex
+
4
);
if
(
number
==
0
)
{
logger
.
Error
(
$"REQ 没有任何寄存器"
);
sendBuf
=
Modbus_DefaultCallback
(
buf
,
startIndex
,
MB_ERR_NUM_0
);
//指令异常
return
req_len
;
}
if
(
number
>
50
)
//限制数量,因为缓存区不够大
number
=
50
;
List
<
byte
>
midBuf
=
new
List
<
byte
>();
midBuf
.
Add
(
deviceNo
);
midBuf
.
Add
(
0x04
);
midBuf
.
Add
((
byte
)(
number
*
2
));
UInt16
[]
regValues
=
new
UInt16
[
number
];
if
(
this
.
regRead_Input
==
null
)
{
//读取失败,没有设备,不用回复
logger
.
Debug
(
$"REQ 读取失败,没有设置regRead,不用回复"
);
sendBuf
=
null
;
return
req_len
;
}
bool
ret
=
this
.
regRead_Input
(
deviceNo
,
startAddr
,
regValues
);
if
(!
ret
)
{
//读取失败,没有设备,不用回复
logger
.
Debug
(
$"REQ 读取失败,没有设备,不用回复"
);
sendBuf
=
null
;
return
req_len
;
}
for
(
int
i
=
0
;
i
<
number
;
i
++)
{
midBuf
.
AddRange
(
regValues
[
i
].
GetBytes_Big_endian
());
}
sendBuf
=
midBuf
.
ToArray
();
return
req_len
;
//Modbus_AddCrcAndSend(midBuf);
}
/// <summary>
/// <summary>
/// Write Single REG
/// Write Single REG
/// </summary>
/// </summary>
...
...
GeneralGommunication/ModbusServer.cs
View file @
156b8a7b
...
@@ -8,7 +8,9 @@ namespace GeneralGommunication
...
@@ -8,7 +8,9 @@ namespace GeneralGommunication
{
{
public
interface
IModbusServer
public
interface
IModbusServer
{
{
void
Init
(
ModbusRegReadWriteHandler
regRead
,
ModbusRegReadWriteHandler
regWrite
,
void
Init
(
ModbusRegReadWriteHandler
regRead_Holding
,
ModbusRegReadWriteHandler
regRead_Input
,
ModbusRegReadWriteHandler
regWrite
,
Action
<
IEnumerable
<
byte
>>
sendMsg
,
out
Action
<
IEnumerable
<
byte
>>
recMsg
);
Action
<
IEnumerable
<
byte
>>
sendMsg
,
out
Action
<
IEnumerable
<
byte
>>
recMsg
);
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment