modbus_rtu V3.0 通信协议串口通讯动态链接库DLL完美版 点击:11392 | 回复:15



wjun7610

    
  • 精华:0帖
  • 求助:0帖
  • 帖子:14帖 | 199回
  • 年度积分:0
  • 历史总积分:436
  • 注册:2004年2月01日
发表于:2008-12-20 19:46:48
楼主

modbus_rtu V3.0 通信协议串口通讯动态链接库DLL(以下简称DLL),是为满足工业通信需要, 

针对工业领域要求上位机对PLC、工业仪表通讯实时采集与控制的组态编程而设计。 

本DLL是采用Delphi语言开发的标准串口通讯库,具有以下特点: 

1)、遵循modbus rtu串口通讯协议(施耐德、西门子、台达、永宏等品牌PLC及各类工业仪表等均支持本协议); 

2)、支持多串口并发操作,支持多线程串口通讯,将串口通讯对主程序的影响降至最低; 

3)、实时性、可靠性好,通用性强; 

4)、适用于多PLC(下位机)联网和上位机通信,满足多方面的需要(联网时可采用485总线式); 

5)、函数接口功能全,操作简单,支持modbus的大部分读写功能函数; 

6)、支持USB、PC扩展卡等扩展串口号; 

7)、支持多种操作系统win9x/win2000/winXP(标注Win32 DLL); 

8)、易于快速开发(VC等非RAD开发环境的开发); 

9)、更新原有函数调用方式采用数组调用数据发生与接收,初学者快速入门; 

10)、可在多种编程环境下使用,例如VB、VC、Delphi等开发环境; 

11)、支持modbus rtu标准的功能代码01、02、03、04、05、06、15、16,并且对相关功能代码作了延伸可以 

读取下位机中的双字、单精度浮点等类型数据,更加符合工业自动化领域的工控软件的开发。 


软件版本更新及相关说明: 

modbus_rtu.dll V3.0串口通讯链接库,实现了对保持寄存器40001~4XXXX区数据读写(FCN03:读、 FCN16:写; 

FCN06写单个数据);对逻辑线圈00001~0XXXX的读写(FCN01:读取一组线圈,FCN05:强置单线圈,FCN15强置多线圈); 

对输入状态10001~1XXXX的读(FCN02);对输入寄存器30001~3XXXX的读(FCN04)。 

wangjun于2008年在原有modbus.dll V2.0版基础上的更新版,重写了函数结构,采用数据接收和发送缓冲区 

(数组)方式传递,读出和写入单元数据使用更方便。对于16位整数和32位整数读取写入均按有符号整数处理, 

小数的返回按单精度浮点型(2进制浮点)处理,提供高位在前或低位在前两种32整数和浮点数据的读取方式。 

 

注意:实例在使用时不能超出试用版的地址限制,否则无法正确通讯。

龙帅工作室为您提供专业串口通讯控件,也可为您订制 专用通讯协议串口控件。目前龙帅系列串口通讯协议 

控件包括modbus_rtu、三菱FX PLC编程口、欧姆龙HostLink、西门子PPI等多个系列产品。 

淘宝店:http://shop34821629.taobao.com 

电 话:13912935690 025-84359545 

腾讯QQ:157610979 

邮 箱:wjun7610@yahoo.com.cn 

chinawanglong@163.com 

157610979@QQ.com 

正在下载,请等待……
下载附件需0积分!




wjun7610

  • 精华:0帖
  • 求助:0帖
  • 帖子:14帖 | 199回
  • 年度积分:0
  • 历史总积分:436
  • 注册:2004年2月01日
发表于:2008-12-20 19:47:59
1楼

 

DLL带有完整电子版手册和使用DEMO。

生命之手

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 2回
  • 年度积分:0
  • 历史总积分:12
  • 注册:2006年3月21日
发表于:2011-04-01 08:11:16
2楼

miy_gongkong

  • 精华:0帖
  • 求助:3帖
  • 帖子:33帖 | 3063回
  • 年度积分:0
  • 历史总积分:12424
  • 注册:2008年9月18日
发表于:2011-04-01 12:14:12
3楼

顶一下!                                         

wjun7610

  • 精华:0帖
  • 求助:0帖
  • 帖子:14帖 | 199回
  • 年度积分:0
  • 历史总积分:436
  • 注册:2004年2月01日
发表于:2011-05-16 21:51:22
4楼
modbus_rtu.dll V3.3 modbus rtu通信协议串口通讯动态链接库DLL(以下简称DLL),是为满足工业通信需要,

针对工业领域要求上位机对PLC、工业仪表通讯实时采集与控制的组态编程而设计。

本DLL是采用Delphi语言开发的标准串口通讯库,具有以下特点:

1)、遵循modbus rtu串口通讯协议;

2)、支持多串口并发操作,支持多线程串口通讯,将串口通讯对主程序的影响降至最低;

3)、实时性、可靠性好,通用性强;

4)、适用于多PLC(下位机)联网和上位机通信,满足多方面的需要;

5)、函数接口功能全,操作简单,支持欧姆龙PLC的绝大部分地址的读写功能函数;

6)、支持USB、PC扩展卡等扩展串口号;

7)、支持多种操作系统win9x/win2000/winXP(标准Win32 DLL);

8)、易于快速开发(VC等非RAD开发环境的开发);

9)、更新原有函数调用方式采用数组调用数据发生与接收,初学者快速入门;

10)、可在多种编程环境下使用,例如VB、VC、Delphi、PB、Labview、易语言等开发环境;

11)、扩展了函数功能读取下位机中的双字、单精度浮点等类型数据,更加符合工业自动化领域的工控软件的开发。

软件版本更新及相关说明:

modbus_rtu.dll V3.3串口通讯链接库,实现了对保持寄存器40001~4XXXX区数据读写(FCN03:读、 FCN16:写;

FCN06写单个数据);对逻辑线圈00001~0XXXX的读写(FCN01:读取一组线圈,FCN05:强置单线圈,FCN15强置多线圈);

对输入状态10001~1XXXX的读(FCN02);对输入寄存器30001~3XXXX的读(FCN04)。

wangjun于2008年在原有modbus.dll V2.0,历经V3.0、V3.2版基础上的更新版,重写了函数结构,采用数据接收

和发送缓冲区(数组)方式传递,读出和写入单元数据使用更方便。对于16位整数和32位整数读取写入均按有符号整数

处理,小数的返回按单精度浮点型(2进制浮点)处理读取方式。提供扩展功能函数,方便用户实现混合数据读取。

能够同时满足32个串口并发情况下的正常使用。

modbus_rtu.dll V3.3 分为完美版和单机版两个版本。

wjun7610

  • 精华:0帖
  • 求助:0帖
  • 帖子:14帖 | 199回
  • 年度积分:0
  • 历史总积分:436
  • 注册:2004年2月01日
发表于:2011-05-16 21:51:48
5楼
在VC中使用DLL一般都是采用动态声明的方式,函数说明中给出的是Delphi的函数原型,

在VC中声明时只要注意一下类型的对应即可,Delphi中的longint类型对应VC中的int类型

Delphi中的Pchar对应VC中的char* ,下面给出主要函数的声明:

在使用的文件的cpp中声明一个句柄:

HINSTANCE hinstDLL;

用来标识导入的动态链接库。

1)、按下例说明声明相关各个函数:(在cpp文件的头处声明)

typedef int (_stdcall *pOpen)(int nport, int BaudRate, int DataBits, char* Parity, int StopBits, char* User);
typedef int (_stdcall *pClose)(int nport);
typedef int (_stdcall *pSetDelay)(int nport);
typedef int (_stdcall *pComTrue)(int nport);
typedef int (_stdcall *pComWork)(int nport);

typedef int (_stdcall *pfcn01)(int nport, int node, int address, int Count,int* RxdBuffer);
typedef int (_stdcall *pfcn02)(int nport, int node, int address, int Count,int* RxdBuffer);
typedef int (_stdcall *pfcn03)(int nport, int node, int address, int Count,int* RxdBuffer);
typedef int (_stdcall *pfcn04)(int nport, int node, int address, int Count,int* RxdBuffer);
typedef int (_stdcall *pfcn05)(int nport, int node, int address, int value);
typedef int (_stdcall *pfcn06)(int nport, int node, int address, int value);
typedef int (_stdcall *pfcn15)(int nport, int node, int address, int Count,int* TxdBuffer);
typedef int (_stdcall *pfcn16)(int nport, int node, int address, int Count,int* TxdBuffer);

typedef int (_stdcall *pfcn03DInt)(int nport, int node, int regular, int address, int Count,int* RxdBuffer);
typedef int (_stdcall *pfcn03Float)(int nport, int node, int regular, int address, int Count,float* RxdBuffer);
typedef int (_stdcall *pfcn04DInt)(int nport, int node, int regular, int address, int Count,int* RxdBuffer);
typedef int (_stdcall *pfcn04Float)(int nport, int node, int regular, int address, int Count,float* RxdBuffer);
typedef int (_stdcall *pfcn16DInt)(int nport, int node, int regular, int address, int Count,int* TxdBuffer);
typedef int (_stdcall *pfcn16Float)(int nport, int node, int regular, int address, int Count,float* TxdBuffer);
typedef int (_stdcall *pWbitWrite)(int nport, int node, int address, int Bit, int value);
typedef int (_stdcall *pWbitSetReset)(int nport, int node, int address, int Bit);

typedef int (_stdcall *pBitBin)(int value, int Bitaddress);
typedef int (_stdcall *p32I_16h)(int value);
typedef int (_stdcall *p32I_16l)(int value);
typedef int (_stdcall *p16I_32I)(int valueH, int valueL);
typedef int (_stdcall *p32f_16h)(float value);
typedef int (_stdcall *p32f_16l)(float value);
typedef float (_stdcall *p16I_32f)(int valueH, int valueL);

2)、建立动态链接库的新函数名:(在cpp文件的头处声明)

pOpen mOpen;
pClose mClose;
pSetDelay mSetDelay;
pComTrue mComTrue;
pComWork mComWork;

pfcn01 mfcn01;
pfcn02 mfcn02;
pfcn03 mfcn03;
pfcn04 mfcn04;
pfcn05 mfcn05;
pfcn06 mfcn06;
pfcn15 mfcn15;
pfcn16 mfcn16;

pfcn03DInt mfcn03DInt;
pfcn03Float mfcn03Float;
pfcn04DInt mfcn04DInt;
pfcn04Float mfcn04Float;
pfcn16DInt mfcn16DInt;
pfcn16Float mfcn16Float;
pWbitWrite mWbitWrite;
pWbitSetReset mWbitSetReset;

pBitBin mBitBin;
p32I_16h m32I_16h;
p32I_16l m32I_16l;
p16I_32I m16I_32I;
p32f_16h m32f_16h;
p32f_16l m32f_16l;
p16I_32f m16I_32f;

3)、导入动态链接库,如例所示:(在cpp文件的OnInitDialog过程建立):

hinstDLL = LoadLibrary("modbus_rtu.dll");

4)、判断dll文件是否存在并声明并建立动态链接库中的函数与新函数名的对应关系,

如下:(在cpp文件的OnInitDialog过程建立):

if (hinstDLL)
{
mOpen = (pOpen)GetProcAddress (hinstDLL,"mbrtuComOpen");
mClose = (pClose)GetProcAddress (hinstDLL,"mbrtuComClose");
mSetDelay = (pSetDelay)GetProcAddress (hinstDLL,"mbrtuSetDelay");
mComTrue = (pComTrue)GetProcAddress (hinstDLL,"mbrtuComTrue");
mComWork = (pComWork)GetProcAddress (hinstDLL,"mbrtuComWork");

mfcn01 = (pfcn01)GetProcAddress (hinstDLL,"mbrtufcn01");
mfcn02 = (pfcn02)GetProcAddress (hinstDLL,"mbrtufcn02");
mfcn03 = (pfcn03)GetProcAddress (hinstDLL,"mbrtufcn03");
mfcn04 = (pfcn04)GetProcAddress (hinstDLL,"mbrtufcn04");
mfcn05 = (pfcn05)GetProcAddress (hinstDLL,"mbrtufcn05");
mfcn06 = (pfcn06)GetProcAddress (hinstDLL,"mbrtufcn06");
mfcn15 = (pfcn15)GetProcAddress (hinstDLL,"mbrtufcn15");
mfcn16 = (pfcn16)GetProcAddress (hinstDLL,"mbrtufcn16");

mfcn03DInt = (pfcn03DInt)GetProcAddress (hinstDLL,"mbrtufcn03DInt");
mfcn03Float = (pfcn03Float)GetProcAddress (hinstDLL,"mbrtufcn03Float");
mfcn04DInt = (pfcn04DInt)GetProcAddress (hinstDLL,"mbrtufcn04DInt");
mfcn04Float = (pfcn04Float)GetProcAddress (hinstDLL,"mbrtufcn04Float");
mfcn16DInt = (pfcn16DInt)GetProcAddress (hinstDLL,"mbrtufcn16DInt");
mfcn16Float = (pfcn16Float)GetProcAddress (hinstDLL,"mbrtufcn16Float");
mWbitWrite = (pWbitWrite)GetProcAddress (hinstDLL,"mbrtuWordBitWrite");
mWbitSetReset = (pWbitSetReset)GetProcAddress (hinstDLL,"mbrtuWordBitSetReset");

mBitBin = (pBitBin)GetProcAddress (hinstDLL,"DecBitBin");
m32I_16h = (p32I_16h)GetProcAddress (hinstDLL,"Int32ToInt_16h");
m32I_16l = (p32I_16l)GetProcAddress (hinstDLL,"Int32ToInt_16l");
m16I_32I= (p16I_32I)GetProcAddress (hinstDLL,"Int16ToInt32");
m32f_16h = (p32f_16h)GetProcAddress (hinstDLL,"Float32ToInt_16h");
m32f_16l = (p32f_16l)GetProcAddress (hinstDLL,"Float32ToInt_16l");
m16I_32f= (p16I_32f)GetProcAddress (hinstDLL,"Int16ToFloat32");

AfxMessageBox("modbus_rtu.dll已成功载入!");
}
else
{
AfxMessageBox("没找到modbus_rtu.dll!");
SendMessage(WM_CLOSE);
}

注:双引号中为动态链接库中的原有函数名。


函数中用到了char*型参数,这里介绍下char*与Cstring的相互转换的函数:

(1)char*->CString

char* sz;
CString str;
str.Format("%s",sz); //可以用此函数将读取的值转成字符串

(2) CString -> char*

CString str;
char* sz = str.GetBuffer(0);//可将字符串转成char*给函数赋值


5)、当不再需要使用DLL时记得关闭串口及释放动态链接库,(在OnDestroy事件中释放)

if(hinstDLL)
{
int k = mComTrue(mnport);
if (k==1)
{
mClose(mnport);
}
FreeLibrary(hinstDLL);
}

wjun7610

  • 精华:0帖
  • 求助:0帖
  • 帖子:14帖 | 199回
  • 年度积分:0
  • 历史总积分:436
  • 注册:2004年2月01日
发表于:2011-05-16 21:52:13
6楼
modbus rtu协议DLL缓冲区传递功能函数包括:

1)、mbrtuClearBuf 清除复位DLL缓存区;

2)、mbrtufcn01Buf 01功能码:取得一组逻辑线圈的当前状态(ON/OFF);

3)、mbrtufcn02Buf 02功能码:取得一组开关输入的当前状态(ON/OFF);

4)、mbrtufcn03Buf 03功能码:在一个或多个保持寄存器中取得当前16位整数值(字);

5)、mbrtufcn04Buf 04功能码:在一个或多个输入寄存器中取得当前16位整数值(字);

6)、mbrtufcn03DIntBuf 03功能码 双字:在2个或多个保持寄存器中取得当前32位整数值(双字由2个寄存器组成);

7)、mbrtufcn04DIntBuf 04功能码 双字:在2个或多个输入寄存器中取得当前32位整数值(双字由2个寄存器组成);

8)、mbrtuIntDllBufRead 读DLL整数缓存区值;

9)、mbrtufcn03FloatBuf 03功能码 浮点:在2个或多个保持寄存器中取得当前32位单精度浮点(浮点由2个寄存器组成);

10)、mbrtufcn04FloatBuf 04功能码 浮点:在2个或多个输入寄存器中取得当前32位单精度浮点(浮点由2个寄存器组成);

11)、mbrtuFloatDllBufRead 读DLL浮点缓存区值;

12)、mbrtuWriteIntDllBuf 写DLL整数缓存区值;

13)、mbrtufcn15Buf 15功能码:强置一串连续逻辑线圈的通断状态(ON/OFF);

14)、mbrtufcn16Buf 16功能码:把16位整数值(字)装入一串连续保持寄存器;

15)、mbrtufcn16DIntBuf 16功能码 双字:把32位整数值(双字由2个寄存器组成)装入2个或多个连续保持寄存器;

16)、mbrtuWriteFloatDllBuf 写DLL浮点缓存区值;

17)、mbrtufcn16FloatBuf 16功能码 浮点:把32位位单精度浮点(浮点由2个寄存器组成)装入2个或多个连续保持寄存器;


这里,仅对PB开发环境使用DLL缓存区数据传递进行调用给出了

申明方式和调用举例,其他非VC、VB、Delphi等语言需要使用DLL

缓冲区进行数据传递时,调用DLL声明请参考本语言对Windows标准

DLL的规则和函数原型进行调用。

能够正确传递数组的开发环境如VB、VC、delphi不推荐使用该部分

扩展功能函数。

wjun7610

  • 精华:0帖
  • 求助:0帖
  • 帖子:14帖 | 199回
  • 年度积分:0
  • 历史总积分:436
  • 注册:2004年2月01日
发表于:2011-05-16 21:52:41
7楼
这里以VB程序为例叙述一下如何进行混合数据的读写。

混合数据的读写,一般都是使用modbus标准地址40001~4XXXX地址区进行操作

这里40001、40002、40005、40006是16位整数元件,40003/40004是32位整数元件,40007/40008是32位单精度浮点元件

1、混合数据的读

Dim nodeI, addrI, ReadInt As Long
Dim buffer(1024) As Long ‘定义一个数据接收缓冲区 整型为1024,浮点型为256
Dim strreal As String
TimerRead.Enabled = False
If (modbuson = 1) Or (mbrtuComTrue(ComPort) <> 1) Or (Readtrue = -1) Then Exit Sub
nodeI = Val(Combnode.Text)
addrI = 0 ‘modbus地址从40001开始,偏移地址0-7,8个存储器值
ReadInt = mbrtufcn03(ComPort, nodeI, addrI, 8, buffer(0)) ‘读取字元件值
If ReadInt = 8 Then
ReadText(0).Text = Trim(Str(buffer(0)))
ReadText(1).Text = Trim(Str(buffer(1)))
If OptionWord01.value Then ‘不同品牌的下位机在双字和浮点的数据存储上有所不同,有高位在前和低位在前之分
ReadText(2).Text = Trim(Str(Int16ToInt32(buffer(3), buffer(2))))
Else
ReadText(2).Text = Trim(Str(Int16ToInt32(buffer(2), buffer(3))))
End If
ReadText(3).Text = Trim(Str(buffer(4)))
ReadText(4).Text = Trim(Str(buffer(5)))
If OptionWord01.value Then ‘不同品牌的下位机在双字和浮点的数据存储上有所不同,有高位在前和低位在前之分
strreal = Trim(Str(Int16ToFloat32(buffer(7), buffer(6))))
Else
strreal = Trim(Str(Int16ToFloat32(buffer(6), buffer(7))))
End If
ReadText(5).Text = Format(strreal, "0.000")
End If

2、混合数据的写

Dim SendInt As Integer
Dim SendFloat As Single
Dim nodeI, addrI, addrBit, ReadInt, SendDint As Long
Dim nameplc As String
Dim buffer(1024) As Long ‘定义一个数据发送缓冲区 整型为1024,浮点型为256

nodeI = Val(Combnode.Text)
addrI = 0 ‘modbus地址从40001开始,偏移地址0-7,8个存储器值
‘将混合的数据转换成16位整数,数组
SendInt = Val(SendText(0).Text) ‘16位整数
buffer(0) = SendInt
SendInt = Val(SendText(1).Text) ‘16位整数
buffer(1) = SendInt
SendDint = Val(SendText(2).Text) ‘32位整数
If OptionWord01.value Then ‘不同品牌的下位机在双字和浮点的数据存储上有所不同,有高位在前和低位在前之分
buffer(2) = Int32ToInt_16l(SendDint)
buffer(3) = Int32ToInt_16h(SendDint)
Else
buffer(2) = Int32ToInt_16h(SendDint)
buffer(3) = Int32ToInt_16l(SendDint)
End If
SendInt = Val(SendText(3).Text) ‘16位整数
buffer(4) = SendInt
SendInt = Val(SendText(4).Text) ‘16位整数
buffer(5) = SendInt
SendFloat = Val(SendText(5).Text) ‘32位浮点数
If OptionWord01.value Then ‘不同品牌的下位机在双字和浮点的数据存储上有所不同,有高位在前和低位在前之分
buffer(6) = Float32ToInt_16l(SendFloat)
buffer(7) = Float32ToInt_16h(SendFloat)
Else
buffer(6) = Float32ToInt_16h(SendFloat)
buffer(7) = Float32ToInt_16l(SendFloat)
End If
‘将混合的数据转换成16位整数,数组
Call mbrtufcn16(ComPort, nodeI, addrI, 8, buffer(0)) ‘按16位整数写入下位机

yuzhuanghui

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 2回
  • 年度积分:0
  • 历史总积分:22
  • 注册:2004年12月13日
发表于:2012-10-09 16:32:04
8楼
ddfgsgfgsadfasgagsf

yuzhuanghui

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 2回
  • 年度积分:0
  • 历史总积分:22
  • 注册:2004年12月13日
发表于:2012-10-31 17:12:54
9楼
fhsfdsfasfdafa

rays530656236

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 1回
  • 年度积分:0
  • 历史总积分:1
  • 注册:2016年4月05日
发表于:2016-04-05 10:17:36
10楼

很牛X,NXNXNXNX

lipyu

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 1回
  • 年度积分:0
  • 历史总积分:1
  • 注册:2010年4月30日
发表于:2016-04-25 16:04:52
11楼

modbus_rtu.dll V3.3 分为完美版和单机版两个版本, 多谢了!

学无

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 5回
  • 年度积分:0
  • 历史总积分:65
  • 注册:2018年7月13日
发表于:2018-07-13 16:51:45
12楼

很牛X,感谢分享


qq177876178

  • 精华:0帖
  • 求助:0帖
  • 帖子:0帖 | 4回
  • 年度积分:0
  • 历史总积分:0
  • 注册:1900年1月01日
发表于:2018-08-19 08:52:30
13楼

modbus_rtu.dll V3.3 分为完美版和单机版两个版本, 多谢了!


热门招聘
相关主题

官方公众号

智造工程师