OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 15921|回复: 20

分享C#搞的modbus主机库【更新库实现方式】

[复制链接]

120

主题

7877

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12010
金钱
12010
注册时间
2013-9-10
在线时间
427 小时
发表于 2018-8-30 22:39:42 | 显示全部楼层 |阅读模式
本帖最后由 八度空间 于 2019-7-12 19:03 编辑

最近周末有点闲时间,就折磨一下modbus在C#上与MCU或者PLC通讯的事情,小有成果

主要是打包成库的方式,方便后续调用

一、库对外提供了基础的函数功能,平常用的比较多的几个
二、ResponseDataBufferMax枚举类
       主要是定义了响应帧不同功能码返回数据缓冲区的大小,目前没想到更好的办法,将就用一下
三、FunctionCode枚举类
       定义了常用的几个modbus功能码
四、ExceptionCode枚举类
       定义了响应异常帧错误码
五、ResponseDecodeRTU对于RTU模式下响应帧调用的API类集合
       5.1、public static string ReceiveString
               此函数主要获取接收的数据帧字符串,可以直接显示到界面的log提示框去
       5.2、public static bool ResponseDecodeFinish
               此函数是获取响应帧是否解码完毕
       5.3、public static bool isAbnormal
               如果响应的是异常帧,此函数返回true,否则false
       5.4、public static string LogMessage
               解码的log信息都在这里了
       5.5、public static int ResultCode
               获取解码函数的错误码
       5.6、public static byte FunctionCode
               获取响应帧的功能码
       5.7、public static byte DeviceID
               获取响应帧的设备ID
       5.8、public static byte ExceptionCode
               获取异常码,也就是0x8x后面所带的那个错误码
       5.9、public static void WriteCoils(out ushort Register, out ushort Value)
               获取写单个线圈响应帧数据
       5.10、public static void WriteHolding(out ushort Register, out ushort Value)
               获取写单个保持寄存器响应帧数据
       5.11、public static void WriteMultiCoils(out ushort StartAddress, out ushort OutputNumber)
               获取写多个线圈响应帧数据
       5.12、public static void WriteMultiHolding(out ushort StartAddress, out ushort RegisterNumber)
               获取写多个保持寄存器响应帧数据
       5.13、public static void ReadCoil(out byte ByteOfCount, out byte[] Status)
               获取读线圈响应帧数据
       5.14、public static void ReadDiscreteInputs(out byte ByteOfCount, out byte[] Status)
               获取读离散输入响应帧数据
       5.15、public static void ReadHolding(out byte ByteOfCount, out byte[] RegisterValue)
               获取读保持寄存器响应帧数据
       5.16、public static void ReadInput(out byte ByteOfCount, out byte[] RegisterValue)
              获取读输入寄存器响应帧数据
       5.17、public static void ReadWriteMultiHolding(out byte ByteOfCount, out byte[] rRegisterValue)
               获取读写多个保持寄存器响应帧数据
六、TransmitRTU对于RTU模式下发送数据帧类集合
       6.1、public static string LogMessage
               获取发送数据log
       6.2、public static string TransmitString
               获取发送数据帧字符串
       6.3、public static bool TransmitFaild
              当发送失败的时候,此函数返回true,否则返回false
       6.4、public static bool ReSendFaild
              当重发失败的时候,此函数返回true,否则返回false,在发送的时候,默认有3此重发机制,当然,重发次数可以修改,后面说到
       6.5、public static int ReSendCount
              设置重发次数,建议不低于3次
       6.6、public static int ReadCoils(ushort Register, ushort Number)
              读取设备线圈
       6.7、public static int ReadDiscreteInput(ushort Register, ushort Number)
              读取设备离散输入
       6.8、public static int ReadHolding(ushort Register, ushort Number)
              读取设备保持寄存器
       6.9、public static int ReadInput(ushort Register, ushort Number)
              读取设备输入寄存器
       6.10、public static int WriteCoils(ushort Register, ushort Data)
              写设备单个线圈状态
       6.11、public static int WriteHolding(ushort Register, ushort Data)
              写设备单个保持寄存器
       6.12、public static int WriteMultipleCoils(ushort Register, ushort Number, List<byte> Data)
              写设备多个线圈状态
        6.13、public static int WriteMultipleHolding(ushort Register, ushort Number, List<byte> Data)
               写设备多个保持寄存器
        6.14、public static int ReadWriteMultipleHolding(ushort rRegister, ushort wRegister, ushort rNumber, ushort wNumber, List<byte> Data)
               读写设备多个保持寄存器
七、public static byte DeviceID
      配置设备通讯ID
八、public static int Initializer(byte pDeviceID, string pPortName, int pBaudRate, int pDataBits, StopBits pStopBits, Parity pParity, bool isIndependentReceivingThread)
      初始化通讯接口,附带有一个线程接收,为true的时候,单独的线程进行接收并处理数据,否则需要在外部调用接收数据处理函数
九、public static void ThreadServerClose()
      在关闭或者退出程序的时候,需要调用此函数进行释放资源,否则将导致意外的情况发生
十、public static void ReceiveCallBack()
      接收数据处理回调函数,当使用独立线程进行处理的时候,此函数不必进行调用,方法见第八点初始化形参配置
十一、public static SerialPort GetSerialPortHandle
      获取串口句柄
十二、其他就是一些关于串口操作的函数,发送和接收计数获取等等

路过大神多多指教

附件提供有基础的测试软件

【2019-07-12】修改了实现方式,和旧版本的动态库操作有所区别,具体函数API如下:
1、比较常用的功能码定义:FunctionCode
2、异常帧(错误帧)中异常码定义:ExceptionCode
3、设置设备ID:SetDeviceID
4、获取发送/接收状态:GetStatus
5、获取响应帧字符串:GetResponseFrame
6、获取响应帧解码返回的错误码信息:GetResponseResultCode
7、获取响应帧数据:GetResponseData
8、获取发送数据帧log信息:GetTransmitLogMessage
9、获取发送数据帧字符串:GetTransmitFrame
10、设置重发次数:SetTransmitReSendCountMax()
11、设置等待应答超时时间:SetTransmitWaitResponseTimeOutMax()
12、发送读线圈数据帧:TransmitReadCoils()
13、发送读离散输入数据帧:TransmitReadDiscreteInput()
14、发送读保持寄存器数据帧:TransmitReadHolding()
15、发送读输入寄存器数据帧:TransmitReadInput()
16、发送写单个线圈数据帧:TransmitWriteCoils()
17、发送写单个保持寄存器数据帧:TransmitWriteHolding()
18、发送写多个线圈数据帧:TransmitWriteMultipleCoils()
19、发送写多个保持寄存器数据帧:TransmitWriteMultipleHolding()
20、发送读写多个保持寄存器数据帧:TransmitReadWriteMultipleHolding()
21、发送诊断数据帧:TransmitDiagnosis()
22、关闭串口:CloseSerialPort()
23、控制库初始化:Initialize()
24、释放控制库资源:Dispose()
25、设置数据传输线程优先级:SetTransmitThreadPriority
26、设置数据传输线程是否后台线程:SetTransmitThreadBackground
27、获取发送数据字节计数:GetTransmitByteCount
28、获取接收数据字节计数:GetReceiveByteCount
29、获取解码异常码:GetExceptionCode
30、注册串口:RegistrationSerialPortControl
31、获取控制库版本:GetLibraryVersion
32、读取数据流:Read()
33、写入数据流:Write()
34、获取寄存器地址:GetRegisterValue

这次增加了诊断函数,受松下A6系列伺服modbus通讯控制启发增加的
顺便弄了新版的测试软件,详见附件
查询返回数据稍微简单一点
  1. res = mbLib.GetStatus(out err);
  2.                     if (res == 0)
  3.                     {
  4.                         this.Invoke(new Action(() =>
  5.                         {
  6.                             modbus_ResponseBytesThreadHandler(err);
  7.                         }));
  8.                         isStartScanFlag = false;
  9.                     }
复制代码
附件压缩包ModbusTest_V1.0-1.zip中动态库文件dll,readme.txt说明文件

ModbusLibraryTest V1.0-2.zip

553.82 KB, 下载次数: 528

ModbusLibrary.zip

10.22 KB, 下载次数: 381

ModbusTest_V1.0-1.zip

137.11 KB, 下载次数: 528

现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

52

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
349
金钱
349
注册时间
2018-7-26
在线时间
75 小时
发表于 2018-8-31 09:35:22 | 显示全部楼层
这么好的东西没人顶?
回复 支持 反对

使用道具 举报

7

主题

105

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1026
金钱
1026
注册时间
2016-1-28
在线时间
134 小时
发表于 2018-10-30 10:42:57 | 显示全部楼层
厉害,谢谢楼主分享~~
回复 支持 反对

使用道具 举报

7

主题

105

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1026
金钱
1026
注册时间
2016-1-28
在线时间
134 小时
发表于 2018-10-30 10:48:16 | 显示全部楼层
楼主有无试过CH375在WIN10 64位平台上的USB通讯C#程序。我的CH375DLL始终无法注册成功~
回复 支持 反对

使用道具 举报

120

主题

7877

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12010
金钱
12010
注册时间
2013-9-10
在线时间
427 小时
 楼主| 发表于 2018-10-31 22:35:34 | 显示全部楼层
qjp1988113 发表于 2018-10-30 10:48
楼主有无试过CH375在WIN10 64位平台上的USB通讯C#程序。我的CH375DLL始终无法注册成功~

没有调用过,还真不知道,是不是要获取管理员权限
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

27

主题

427

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
4355
金钱
4355
注册时间
2017-5-30
在线时间
577 小时
发表于 2018-12-27 18:27:48 | 显示全部楼层
看楼主分享了很多关于MODBUS的文章。想请问一下楼主在使用freemodbus使用过多串口。
就是说在串口1 串口2 串口3上同时跑freemodbus。
回复 支持 反对

使用道具 举报

3

主题

1155

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
7462
金钱
7462
注册时间
2015-1-15
在线时间
1367 小时
发表于 2018-12-27 21:15:14 来自手机 | 显示全部楼层
楼主都用CSHAPE了,网上都成现成的MODBUS-RTU和MODBUS-TCP库文件可以使用,稳定性比你自己写的高很多,或者可以把库里的代码拷贝出来利用,修改一下为自己所用
回复 支持 反对

使用道具 举报

120

主题

7877

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12010
金钱
12010
注册时间
2013-9-10
在线时间
427 小时
 楼主| 发表于 2018-12-29 21:23:48 | 显示全部楼层
yklstudent 发表于 2018-12-27 21:15
楼主都用CSHAPE了,网上都成现成的MODBUS-RTU和MODBUS-TCP库文件可以使用,稳定性比你自己写的高很多,或者 ...

最近做项目蛋疼写了一个,网上的没有查
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

120

主题

7877

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12010
金钱
12010
注册时间
2013-9-10
在线时间
427 小时
 楼主| 发表于 2018-12-29 21:24:09 | 显示全部楼层
yklstudent 发表于 2018-12-27 21:15
楼主都用CSHAPE了,网上都成现成的MODBUS-RTU和MODBUS-TCP库文件可以使用,稳定性比你自己写的高很多,或者 ...

发几个出来look look
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

120

主题

7877

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12010
金钱
12010
注册时间
2013-9-10
在线时间
427 小时
 楼主| 发表于 2018-12-29 21:24:50 | 显示全部楼层
whj467467274672 发表于 2018-12-27 18:27
看楼主分享了很多关于MODBUS的文章。想请问一下楼主在使用freemodbus使用过多串口。
就是说在串口1 串口2  ...

我就一个串口跑,没试过几个串口同时跑的,这个是总线协议,不用拆辣么多口的
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

3

主题

1155

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
7462
金钱
7462
注册时间
2015-1-15
在线时间
1367 小时
发表于 2018-12-29 21:38:42 | 显示全部楼层

https://www.modbustools.com/
这个官网可以自己去了解了解
一分耕耘一分收获。
回复 支持 反对

使用道具 举报

27

主题

427

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
4355
金钱
4355
注册时间
2017-5-30
在线时间
577 小时
发表于 2018-12-30 09:17:20 | 显示全部楼层
八度空间 发表于 2018-12-29 21:24
我就一个串口跑,没试过几个串口同时跑的,这个是总线协议,不用拆辣么多口的

我目前是想对接到2个上位机
回复 支持 反对

使用道具 举报

120

主题

7877

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12010
金钱
12010
注册时间
2013-9-10
在线时间
427 小时
 楼主| 发表于 2018-12-31 14:53:03 | 显示全部楼层
whj467467274672 发表于 2018-12-30 09:17
我目前是想对接到2个上位机

哦哦
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

0

主题

160

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
226
金钱
226
注册时间
2019-3-4
在线时间
4 小时
发表于 2019-3-29 10:11:06 | 显示全部楼层
谢谢分享!
回复 支持 反对

使用道具 举报

15

主题

78

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
282
金钱
282
注册时间
2018-4-25
在线时间
45 小时
发表于 2019-3-29 14:29:48 | 显示全部楼层
顶一手啊,好东西
回复 支持 反对

使用道具 举报

4

主题

35

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
241
金钱
241
注册时间
2013-8-3
在线时间
62 小时
发表于 2020-2-13 19:51:28 | 显示全部楼层
谢谢楼主,一直想学习写个上位机用来调下位机,可是不会写,现在可以好好学习一下了
回复 支持 反对

使用道具 举报

8

主题

24

帖子

0

精华

初级会员

Rank: 2

积分
51
金钱
51
注册时间
2019-8-14
在线时间
14 小时
发表于 2020-3-2 12:31:36 | 显示全部楼层
在学modbus,现在是一头雾水
回复 支持 反对

使用道具 举报

0

主题

6

帖子

0

精华

初级会员

Rank: 2

积分
143
金钱
143
注册时间
2012-3-11
在线时间
10 小时
发表于 2021-7-10 16:44:04 | 显示全部楼层
下载学习,谢谢发帖。
回复 支持 反对

使用道具 举报

1

主题

9

帖子

0

精华

初级会员

Rank: 2

积分
97
金钱
97
注册时间
2013-12-10
在线时间
21 小时
发表于 2021-10-27 17:56:30 | 显示全部楼层
本帖最后由 jllhzzj 于 2021-10-27 19:01 编辑

public static string TransmitString { get; }    这个 TransmitString方法的第一个数据没有,要等到下一个时间才显示,收发都没有问题,估计是这个方法的更新时间不对。
2021/10/27 17:51:13
发送[0000Bytes]:
2021/10/27 17:53:26
发送[0008Bytes]: 01 03 00 01 00 01 D5 CA
2021/10/27 17:51:13
接收[0007Bytes]: 01 03 02 00 17 F8 4A
2021/10/27 17:53:26
接收[0007Bytes]: 01 03 02 00 17 F8 4A
我也改不了里面的程序,你们谁测试了?  发现我用的是老版本的库,新版本变化也是有点大,算了,不改了将就着用吧。

回复 支持 反对

使用道具 举报

120

主题

7877

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12010
金钱
12010
注册时间
2013-9-10
在线时间
427 小时
 楼主| 发表于 2021-10-30 18:54:56 | 显示全部楼层
jllhzzj 发表于 2021-10-27 17:56
public static string TransmitString { get; }    这个 TransmitString方法的第一个数据没有,要等到 ...

先记下了,回头看看,好久没弄了,最近弄蓝牙去了
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

0

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
193
金钱
193
注册时间
2019-12-13
在线时间
17 小时
发表于 2023-11-9 12:52:34 | 显示全部楼层
谢谢楼主分享~~
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 10:26

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表