当前位置:城玮文档网 >作文大全 > 组态王软件驱动程序开发

组态王软件驱动程序开发

时间:2022-07-29 08:55:03 来源:网友投稿

 组态王驱动开发包 用户手册

 北京亚控科技发展有限公司 1. 版权 本开发包版权属于北京亚控科技发展有限公司,任何组织、团体、个人,未经亚控 公司允许,不得擅自拷贝,使用,对于购买本开发包的组织、团体、个人,只能内部使用, 不得擅自泄漏给第三方。

 2. 概述 本开发包采用微软标准的 COM 组件技术,采用该技术, 在创建接口时,可以创建 多个互相独立对象,每个对象都可以拥有自己的变量。

 最后的结果是一个 DLL 文件。接口中的各函数,是被组态王的两个应用程序 ---TouchExplorer.exe 和 TouchVew.exe 调用的。如果这两个应用程序都不启动,函数中的 代码将永远没有机会执行。

 组态王的驱动程序 是组态王和硬件设备连接的桥梁,本开发包用于开发组态王的驱动 程序。

 只要拥有硬件的通讯协议,即可以使用本开发包开发组态王的驱动程序。

 本开发包只能使用 VC++ 开发。

 3. 开发包 3.0 修订目的 a) 通用版和嵌入版统一到一套代码中,通用版和嵌入版实现同步更新。

 b) 生成设备类,为多设备型号驱动提供解决方法。

 c) 详尽、稳健的基类代码。

 d) 完善的功能与向导。

 e) 规范各类帮助函数。

 f) 规范编码格式、统一使用英文版。

 g) 修改部分功能的实现方法。

 4. 开发包使用 我们提供一个开发向导工具“ DriverToolKit3.0.0.0.exe ”, 使用这个工具,能够自动地 生成驱动代码框架。

 运行工具,如下图:

 请在下页输入您的目标文件夹

 点击“安装,开发包即安装完成。

 使用开发包向导创建驱动的过程:

 (1) 启动 Visual Studio.NET2003 。

 (2) 新建一个工程,"项目类型”选择 Visual C++ 项目:"模板”选择 KingView Wizard ” , 在下面的编辑框中输入工程的名字以及存储路径,点击“确定” 。

 (3) 这个创建向导分 3 页,第一页是“概述”,显示的是默认的设置信息,如果您不需要 改变这些,直接点击“确定”即可成功的创建驱动框架。

 (4 )第二页是 驱动类型 :

 o 串口驱动 ( 适用于查询式设备 )

 这个类型,是我们一般常用的,适合于普通的上位查询,设备应答的通讯类 型。

 串口驱动 ( 适用于实时上发数据的设备,非重叠 10)

 这种方式,适用于下位设备实时上发数据的情况, 驱动中需要创建一个线程 来监视串口事件的通讯类型,采用非重叠 10 方式。

 串口驱动 ( 适用于实时上发数据的设备,重叠 10 , WinCE 不支持 )

 这种方式,同上一种,也是适用于下位设备实时上发数据的情况,驱动中需 要创建一个线程来监视串口的通讯类型。

 与前一种不同的是:采用了重叠 10 方式。我们不推荐使用这种方式,因为 WINCE 系统不支持这种方式,使用 这种方式开发的驱动,将不能在 WINCE 系统的嵌入式设备中运行。

 以太网驱动 ( TCP 服务器端 )

 这是针对于 TCP 方式通讯的驱动,适用于设备为客户端,组态王为 Server , 组态王查询,设备应答的通讯类型。如果遇到设备主动实时上发数据的情况, 驱动中提供了相应的函数,可以直接调用函数,启动线程来监听网络事 件。

 o 以太网驱动 ( TCP 客户端 )

 “驱动类型和编译选项”,包含如下部分:

 这是 TCP 方式通讯客户端的驱动,适用于组态王查询、设备应答的通讯类 型。这种方式需要驱动主动去连接设备。

 如果遇到设备主动实时上发数据的 情况,驱动中提供了相应的函数,可以直接调用函数,启动线程来监听网络 事件。

 o 以太网驱动 ( UDP 服务器端 )

 目前还没有实现,参考 TCP 方式,代码中需要改动的地方有标注。

 o 以太网驱动 (UDP 客户端 )

 目前还没有实现,参考 TCP 方式,代码中需要改动的地方有标注。

 设备名称 :

 默认的设备名称是 Namel ",可以自由填写,但须注意应该 与设备列表中的设备名 称保持一致。

 尝试连接类型 :

 当组态王与设备通讯失败了,组态王会周期性的尝试与设备通讯,这个过程,我们 称之为“尝试连接”。

 尝试连接,目前准备了如下几种类型:

 o 永远为 True, 常用于板卡驱动。

 o 程序员自由定义,常用于网络通讯或实时上发数据的设备。

 o 使用 PACKET ”进行通讯,适用于普通的驱动。

 ( 5 )第三页是“驱动基本信息”,包含如下条目:

  驱动基本信息 o 驱动名称 o 版本 o 描述 o 程序员 o 项目经理

 这些信息将被自动保存到历史文件 ( History.txt )中,同时也是保存在工程的 ReadMe 文件中,可以随工程浏览。

 其他支持 :

 o USB 通讯 o ADO 数据库操作 ( 6 )点击“确定”后,将完成驱动工程的创建工作。

 5. 工程转换工具 我们要求 通用版和嵌入版使用同一套代码, 做到通用版和嵌入版驱动实现同步更新 , 这就需要一个工具来将通用版工程文件转换为嵌入版工程文件。

 同时,考虑到有的开发者习惯使用 Visual Studio 98 进行开发编译,我们也要有一 个工具来将 Visual Studio 2003 的工程文件转换成 Visual Studio 98 的工程文件。

 我们提供一个转换工具 kvdriver (包含 3 个文件, kvdriver.exe, vc7tovc6.exe,vc7toevc.exe )

 ,使用这个工具,可以根据 Visual Studio 2003 的工程文件, 创建成 Visual Studio 98 和 EVC 的工程文件,开发者可以在不同的开发环境间自由选择。

 驱动开发包安装完成后,这个工具存放在目录 Kin gViewDriver 下。

 在使用的时候,可以把这个工具放在系统文件夹 C:\WINDOWS\system32 中,这样 可以在命令行中输入“ kvdriver ,然后把需要转换的 Visual Studio 2003 工程文件拖 动过来运行即可,如下所示:

 6. 驱动信息结构 所有的结构都定义在文件 “Data 类型.h”中< _DevAddr 该结构定义了设备地址格式 . 类型 def struct _DevAddr { UINT n DevAddr; TCHAR sDevAddr[MAX_DEV_LEN]; }DEVADDR, * PDEVADDR; 成员 :

 sDevAddr: 用户在组态王中输入的原地址格式字符串。

 nDevAddr: 实际转换后的设备地址数字 . ComDevice 这是串口设置信息的结构体 . truct ComDevice short nF lag; WORD deviceKi nd; TCHAR deviceName[32]; int baudRate; short dataBits; short stopBits; short parity; short timeOut; short failTimes; short retryI nterval; short isRs232;

 成员:

 nFlag : 串口标志,目前没有用到 • DeviceKind : 设备类型, "1" 代表串口设备 DeviceName : 逻辑名称 =={C0M1 , COM2...} BaudRate : 波特率,范围是从 110 到 256000 。

 DataBits : 数据位 StopBits : 停止位 . 值 描述 ONESTOPBIT 1 停止位 ONE5STOPBITS 1.5 停止位 TWOSTOPBITS 2 停止位

  Parity : 校验 . 值 描述 EVENPARITY 偶校验 MARKPARITY 标志校验 NOPARITY 无校验 ODDPARITY 奇校验 SPACEPARITY 空格校验 TimeOut :超时,单位是毫秒 FailTimes : 失败次数

 Retrylnterval :尝试间隔 isRs232 :通讯模式, "1" 代表 RS232, 2 代表 RS422, 3 代表 RS485. PLCVAR 该结构定义了用户变量的属性 • 类型 def struct var { WORD wVarlD; WORD wVarType; TCHAR szVarName[32]; short n Device In dex; short nUni tNo; DEVADDR *pDevAddr; TCHAR *pszRegName; short n RegType; short n SubType; short n SubTypel; short n SubType2; short nNo; short n DataType; short n AccessMode; long nF reque ncy; long n TimerC ount; CWin Thread* pComThread; DDEValue maxRaw; DDEValue min Raw; short bCon verti on; short isBad; short isUn valid; }PLCVAR, * PPLCVAR;

 成员:

 wvarlD: 变量 ID wVarType: 变量类型,为如下几种:

 Bit, byte, int, uint, BCD, long, float, longbcd, string szVarName: 变量名 nDevicelndex: 设备索引 nUnitNo:设备 地址单元 pDevAddr: 设备地址

 pszRegName: 寄存器名称 nRegType; 寄存器类型 nSub Type : nSub Type 1: nSub Type 2: 子类型,没有用到,如在驱动中有其他需要,可以自己定义使用。

 nNo : 寄存器通道 n Data Type : 数据类型 nAccessMode: 读写属性 nFrequency: 采集频率 nTimerCount: 超时次数 pComThread: 通讯线程 maxRaw: 最大原始值 minRaw: 最小原始值 PACKET 该结构定义了通讯包的属性 类型 def struct Packet { short n Device In dex; short nUni tNo; DEVADDR * pDevAddr; TCHAR * pszDevName; TCHAR *pszRegName; short n RegType; short n SubType; short n SubTypel; short n SubType2; int nStartNo; int nEn dNo; short n PacketType; CPtrList varList; }PACKET,* PPACKET; 成员:

 nDevicelndex: 设备索引 nUnitNo:设备 地址单元

 pDevAddr: 设备地址结构指针 pszDevName: 设备地址 nRegType: 寄存器类型 n SubType: nSubTypel: nSubType2: 子类型,没有用到,自己可以使用 nStartNo: 开始通道 nEndNo: 结束通道 nPacketType: 包读写类型 VarList: 变量列表,存储 ID_NO 和 ID_NO2 两种类型变量 ID_NO 该结构定义了老的接口的变量 类型 def struct IdNo { WORD wVarId; WORD wNo; WORD wDataType; BYTE Special[4]; PlcValue plcValue; }ID_NO; 成员:

 wVarId : 变量 ID wNo: 通道 wDataType: 数据类型 Special: 目前没有使用 plcValue: PLCVAR 结构体指针 ID_NO2 该结构定义了新的接口的变量 类型 def struct IdNo2 { WORD wVarId; WORD wNo; WORD wData Type ; PlcValue plcValue; BYTE Special[4]; WORD wQualities;

 FILETIME ftTimeStamps; }ID_N02; 成员:

 wVarld :变量 ID wNo: 通道 wDataType: 数据类型 Special: 目前没有用到 plcValue: PLCVAR 结构体指针 wQualities: 质量戳, OxcO 代表 GOOD, 0 代表 BAD. ftTimeStamps: 时间戳,在驱动中一般设置当前的时间 DEVICE 」 NFO 该结构定义了设备信息 类型 def struct device info { TCHAR sDeviceName[32]; }DEVICE_INFO; 成员:

 SDeviceName: 设备名称,最大允许长度是 32 ,使用 TCHAR 字符 REG_INFO 该结构定义了寄存器信息 类型 def struct reginfo ■ ■ TCHAR sRegName[8]; int n Low In dex; int nU pperI ndex; WORD wDataType; int n Data; }REG INFO; 成员:

 sRegName: 寄存器名称 nLowIndex: 开始通道 n Upper In dex: 结束通道

 7. 接口函数 7.1 接口描述 组态王与驱动交互,包括 2 个 COM 接口 :

 lprotocollmp( 老接口 ) 和 IProtocollmp2( 新 接口 ) IProtocollmp::StrToDevAddr XProtocollmp::StrToDevAddr(co nst TCHAR* str, LPVOID lpDevAddr) 类型 :Public 目的 : 实现对地址输入的整理, 判断用户输入的地址是否合法,并 将地址的数值传给组态王 , 如果必要,也可以将地址以字符串的形式传给组态王。

 返回值 : 成功返回 TRUE, 否则返回 FALSE 参数 Str:[in] 用户输入的地址字符串 lpDevAddr:[i n,out]用于保存地址信息的结构 XProtocollmp::GetRegisters XProtocollmp::GetRegisters(co nst TCHAR* szDeviceName, LPVOID * ppRegs, i nt *pRegNum ) 类型 :Public 目的 : 得到由 szDeviceName 确定的寄存器的名字和个数 返回值 ; 成功返回 TRUE, 否则返回 FALSE 参数 szDeviceName [in] 设备的唯一名字 ppReg [out] 返回寄存器信息的指针数组的指针。如果 szDeviceName 无效,则返回 NULL 。

 pRegNum [out] 返回寄存器的个数,如果 szDeviceName 无效,则返回 0 。

 XProtocollmp::ConvertUserConfigToVar XProtocollmp:: Con vertUserCo nfigToVar( LPVOID lpDbltemltem, LPVOID lpVar) 类型 Public

 目的 将用户的配置字符串转换为组态王变量结构 返回值 WORD :如果转换成功则返回 0 ,否则返回非零的错误代码 参数 IpDbltem [in] 指向结构 MiniDbltem 的指针 IpVar [in,out] 指向结构 PLCVAR 的指针,返回变量就存放在这里 XProtocollmp::AddVarToPacket ::AddVarToPacket( LPVOID lpVar, i nt nV arAccessType, LPVOID lpPacket) 类型 Public 目的 确认变量是否能够与一个包里的其他变量一起进行采集, 以进行变量的打包 , 如果可以加入 返回 TRUE 并修改包的起止地址 ; 否则返回 FALSE 。

 返回值 BOOL : FALSE 表示不能打包,否则能 参数 lpVar [in] 变量指针 n VarAccessType [in] 读写方式 lpPacket [out] 包指针

 XProtocolImp::OpenComDevice XProtocolImp::OpenComDevice( int nDeviceType, LPVOID lpInitData) 类型 Public 目的 初始化通讯设备如 :

 ( 串口或板卡等 ) 返回值 BOOL :成功则返回 TRUE ,否则返回 FALSE 参数 nDevice Type [in] 设备类型 lpI ni tData [in] 一个指向 COMM_CONFIG 结构的指针 XProtocollmp::lnitialDevice XProtocollmp::l ni tialDevice(co nst TCHAR* pDeviceName, int nUni tAddr, LPVOID pDevAddr) 类型 Public 目的 初始化设备 , 设置该设备的初始化状态 返回值 BOOL :如果 szDeviceName 有效,则返回 TRUE ,否则返回 FALSE 。

 参数 pDeviceName [in] 设备的唯一名字 nUni tAddr [in] 设备地址 lpDevAddr [in] 应将此参数转换为结构 ---PDEVADDR 。此结构详情参阅 DATA 类型 .H 文件。

 XProtocollmp::ProcessPacket XProtocolImp:: ProcessPacket(LPVOID lpPacket) 类型 Public 目的 根据协议及包状态信息进行相应的处理 ,例如进行读写处理,如果读成功则把数据写入 pPac->varList 。

 返回值 BOOL :如果成功,返回 TRUE ,否则,返回 FALSE 。

 参数 IpPacket [In, out] 包指针 XProtocollmp::CloseComDevice XProtocollmp::CloseComDevice() 类型: Public 目的 : 关闭该通讯设备 返回值 BOOL :成功则返回 TRUE ,否则返回 FALSE 。

 参数 Null XProtocolImp::TryConnect XProtocolImp::TryCo nn ect(co nst TCHAR* pDeviceName, int nUni tAddr, LPVOID pDevAddr) 类型 :Public 目的 : 与地址为 UnitAddr 的设备尝试进行通讯 , 用于故障侦探及恢复尝试。

 返回值 尝试通讯成功返回 TRUE ,否则返回 FALSE 。

 参数 pDeviceName [in] 设备的唯一名字

 nUni tAddr [in] 需要进行故障侦探及恢复尝试的设备的地址。

 lpDevAddr [in] 应将此参数转换为结构 ---PDEVADDR 。此结构详情参阅 DATA 类型 .H 文件。

 备注 当 "ProcessPacket" 失败后 , "TryConnect" 将被组态王调用 2 次,如果仍然失败,则该接口 将按设定的尝试连接间隔被组态王调用。

 XProtocollmp::GetLastError XProtocollmp::GetLastError() 类型 Public 目的 返回最近一次的错误信息。

 返回值 将最近一次的错误信息。

 参数 无 XProtocollmp2::GetTrans XProtocolImp2::GetTra ns( LPVOID* pHcomm) 类型 Public 目的 获取驱动打开的设备句柄,以便其他设备可以使用此句柄 返回值 成功返回 TRUE, 否则返回 FALSE 。

 参数 lpHcomm [out] 接受设备句柄的指针 XProtocolImp2::SetTrans XProtocolImp2::SetTra ns( LPVOID* pHcomm ) 类型 :Public 目的 : 将其他驱动打开的设备句柄传递给驱动 返回值: 成功返回 TRUE, 否则返回 FALSE 。

 参数

 lpHcomm [in] 其他驱动打开的设备句柄。

 XProtocollmp2::ProcessPacket2 XProtocollmp2:: ProcessPacket2(LPVOID IpPacket) 类型 Public 目的 根据协议及包状态信息进行相应的处理 ,例如进行读写处理,如果读成功则把数据写入 pPac->varList 。

 返回值 BOOL :如果成功,返回 TRUE ,否则,返回 FALSE 。

 参数 lpPacket [in,out] 包指针 7.2 接口函数的调用 7.2.1 开发环境 7.2.1.1 新建设备 在向导页输入地址字符串时,程序加载驱动,并调用驱动的 StrToDevAddr

  当向导页转向下一页,也就是点击下一步时,组态王会调用 StrDevToAddr, 并将用 户输入传递给驱动。

 驱动的功能是进行地址转换,具体解释参见 StrDevToAddr 。

 7.2.1.2 新建变量 用户在变量字典里面点击新建变量时, 会弹出如下建立变量的对话框,

 若用户有不是驱动使用域填写有误或者有相关的域 ( 包括驱动使用域 )

 没有填写 , 组态王 将会给出相应的提示 , 即组态王不调用驱动,直接给出错误提示。

 当用户点击连接设备完成设备连接或者在设备组合框中选定设备时,组态王会调用 GetRegisters, 组态王会将设备名称传递给驱动,由驱动返回给组态王寄存器列表 。具体解 释参见 GetRegisters 。

 所有用户必填域填写完毕,切换 TAB 页或者确定变量时,组态王会调用 ConvertUserConfigToVar . 由驱动进行变量校验 。

 MiniDblt em, nDat aTyre 骊动使用输入域,对应 NimDbltth MmiDblt eir,. isRegi^tet [128}

 组态王会将驱动域的输入作为 MiniDbltem 传递给驱动, ConvertUserConfigToVar 将结 果返回在组态王建立的变量 PLCVAR 中 。

 具体解释见 ConvertUserConfigToVar 。

 721.3 串口设备测试 若用户使用的设备是串口设备, 可以方便的使用 串口设备测试工具 进行测试 • 用户进 入测试设备对话框,如下图所示:

 当用户进入此对话框时,组态王立刻调用 GetRegisters 获取设备可以使用的寄存器列 表。

 当用户点击添加或者加入变量时, 组态王立刻调用 ConvertUserConfigToVar 进行变量 校验。

 当用户点击读取, 组态王就开始变量采集。

 所有采集步骤与运行环境一致, 只是这儿测 试只是测试一个设备 ,而运行环境采集定义的所有的设备。

 7.2.2. 运行环境 以下步骤为特殊目的时,组态王对于每个设备都会调用一次此函数。

 7.2.2.1 校验设备地址 调用 StrToDevAddr , 对用户输入的地址字符串进行转换 . 若 StrToDevAddr 返回 TRUE , 转 7.2.2.2. 否则组态王提示用户地址格式不对,同时中止此设备的采集,不影响使用同一 驱动的其他设备。

 7.2.2.2 打开设备 调用 OpenComDevice , 若是串口设备 , 则驱动应在此中进行串口初始化 . 若不是串口驱 动 , 驱动可以在此中完成一次性的初始化工作 。

 若 OpenComDevice 返回 TRUE ,组态王会在信息窗口提示打开设备成功,并给出成 功的设备名称,同时转 7.2.2.3 。否则组态王会在信息窗口提示打开设备失败,认为设备存 在问题,若是串口设备,此串口下连接的所有设备都不能通信, 若是其他类型设备,则此种设备全部不能通信。

 OpenComDevice 的参数由用户配置 。

  7.223 设备初始化 调用 InitialDevice, 对设备进行初始化 • 若 InitialDevice 返回 TRUE ,转 7224 否则 组态王在信息提示用户设备初始化失败, 同时中止此设备的采集, 不影响使用同一驱动的其 他设备。

 7.224 变量校验 调用 ConvertUserConfigToVar 对所有变量进行 变量校验。若一个设备使用的所有变量 都成功,转 7.225 。若某一个设备中有一个变量校验失败,则组态王会在信息窗口提示变 量校验无效,同时组态王会中止此设备的采集。

 7.2.2.5 变量打包 调用 AddVarToPacket 对变量进行打包处理 . 对于属于同一驱动的所有变量进行打包 处理,当所有变量打包完成, 7.2.2.6 。

 7.2.2.6 设备通信 调用 ProcessPacket2 进行设备通信 , 若返回 TRUE ,则释放 7.2.2.5 中建立的 PACKET, 同时进行下一个 PACKET 处理 . 当按照刷新频率全部处理完毕,转 7.2.2.5 重新打 包通信 . 若返回 FALSE ,则转 7.2.2.7 。

 7.2.2.7 尝试恢复设备通信 调用 TryConnect 进行设备尝试恢复 , 若返回 TRUE ,则返回 7.2.2.6 进行正常通信处理。

 若返回失败组态王会再次调用 TryConnect ,若仍然返回 FALSE ,组态王认为设备失败,会 中止设备采集一段时间,在定义设备时设置。

 Crevice. tiieQut "oiTevice. L 畝卫 32 亚和隹祟辅人域 HM :

 evic£

 7.2.2.8 关闭设备 调用 CloseComDevice 关闭设备 , 若 CloseComDevice 返回 FALSE 或者迟迟不能完 成关闭设备动作,将大大影响组态王的退出速度,甚至可能阻止组态王退出。

 8 程序结构 程序包含如下几个 主要的类 : 驱动工程类 (Cpro): 实现 2 个接口 : IprotocolImp 和 IprotocolImp2 。

 设备类 (CDev): 实现 COM 接口, 包括 2 个类,设备基类和设备子类 。

 通讯类 (CCom): 实现串口 ,网卡等的通讯 ,开发包向导会根据您的设置 ,自动地产生串口通 讯类 (CSerialCom) 或者网络通讯类 (CNetCom), 您也可以根据需要添加 USB 通讯类(CUSBCom)。

 调试信息类 (CDebug): 该类实现各种 调试信息在组态王信息窗口中的输出 ,比如 错误信息,接口 信息,数据信息 等。

 帮助函数 (CHelper): 提供了一系列 您在开发驱动过程中可能会用到的功能函数 。

 数据桢校验类 (CCheck): 提供了在开发中会遇到的各种校验函数, 包括和校验、异或校验、 循环冗 余校验 等。

 类的调用与继承关系,如下图:

 ^ProcessPacket^Q ^3etTrans() ^GetTransQ ^SetlnitiaiStnngO

  8.1 驱动工程类 ( CPro)

 该类实现 2 个接口 :

 Iprotocollmp 和 Iprotocollmp2 。

 ^>m_ComObj ^m_DevList 场 m 」LastErrorCode ^GetDevObjQ 丿 、、 o o iProtoco^Irrip IPrcrtocoilmp2 ♦StrToDevAddrO ^GetRegistersQ •Co nve rtUs erC onfigT oVarQ ^AddVarToPacketO ^OpenComDeviceQ ^InitialDeviceQ ^LoadDevicelrifoQ ^Proces:sPacketQ ^CloseCorriDeviceO ^TryConnectO ^GetLastErroifi 关于接口函数目的,见“7.1 ”节。

 8.2 设备类 ( CDev)

 CHelper 实现 COM 接口,包含 2 个类,设备基类 (CDevBase)

 和设备子类 ( CDev)

 。

  类 CDevBase 是所有设备子类的父类。

 属性 :

 m_szDevKind :设备类型. m_pSerialCom :串口通讯类指针 m_pCheck:校验类指针 m_pPro:工程类指针 操作 :

 GetRegisters BOOL CDev::GetRegisters( LPVOID *ppReg, i nt *pRegNum ) 类型 Public 目的 得到由 szDeviceName 确定的寄存器的名字和个数 。

 返回值 成功返回 TRUE,否则返回 FALSE。

 参数 ppReg

 [out]返回寄存器信息的指针数组的指针。

 pRegNum [out]返回寄存器的个数。

 GetDevices BOOL CDev::GetDevices(LPVOID *ppDevice, i nt *pDeviceNum) 类型:Public 目的:得到设备的名字和个数。

 返回值:成功返回 TRUE,否则返回 FALSE。

 参数:ppDevice [out]返回设备列表信息的指针。

 pDeviceNum:[out] 返回设备的个数。

 Conv ertUserC on figToVar WORD CDev::Co nvertUserCo nfigToVar( LPVOID lpDbItemItem, LPVOID lpVar) 类型:Public 目的:将用户的配置字符串转换为组态王变量结构 返回值:WORD :如果转换成功则返回 0,否则返回非零的错误代码。

 参数 lpDbltem:[in] 指向结构 MiniDbltem 的指针。

 lpVar:[in,out]指向结构 PLCVAR 的指针,返回变量就存放在这里。

 AddVarToPacket BOOL CDev::AddVarToPacket( LPVOID lpVar, i nt nV arAccessType, LPVOID lpPacket) 类型 Public 目的 确认变量是否能够与一个包里的其他变量一起进行采集, 以进行变量的打包 , 如 果可以加入 , 返回 TRUE 并修改包的起止地址 ; 否则返回 FALSE。

 返回值 BOOL : FALSE 表示不能打包,否则能。

 参数 lpVar

 [in] 变量指针 n VarAccessType [in] 读写方式 IpPacket [int]包指针 ProcessPacket2 BOOL CDev::ProcessPacket2( LPVOID IpPacket ) 类型 Public 目的 根据协议及包状态信息进行相应的处理,例如进行读写处理,如果读成功则把数 据写入 pPac->varList。(在新接口中调用)。

 返回值 BOOL :如果成功,返回 TRUE,否则,返回 FALSE。

 参数 lpPacket [in,out]包指针。

 TryC onn ect BOOL CDev::TryCo nnect ( const TCHAR* szDeviceName, i nt iUn itAddr, LPVOID lpDevAddr ) 类型 Public 目的 与地址为 UnitAddr 的设备尝试进行通讯 , 用于故障侦探及恢复尝试。

 返回值 尝试通讯成功返回 TRUE,否则返回 FALSE。

 参数 pDeviceName [in] 设备的唯一名字。

 nUni tAddr [in] 需要进行故障侦探及恢复尝试的设备的地址。

 lpDevAddr [in] 应将此参数转换为结构---PDEVADDR。此结构详情参阅 DATATYPE.H 文件。

 备注 当"ProcessPacket"失败后 , "TryConnect"将被组态王调用 2 次,如果仍然失败, 则该接口将按设定的尝试连接间隔被组态王调用。

 StrToDevAddr BOOL CDevBase::StrToDevAddr(co nst TCHAR* str, LPVOID IpDevAddr) 类型:Public 目的:实现对地址输入的整理,判断用户输入的地址是否合法,并将地址的数值 传给组态王,如果必要,也可以将地址以字符串的形式传给组态王 。

 返回值:成功返回 TRUE,否则返回 FALSE 。

 参数 str [in] 用户输入的地址字符串。

 lpDevAddr [in,out]用于保存地址信息的结构。

 SetProPtr void CDevBase::SetProPtr(CProject16Pro* pPro) 类型 Public 目的 设置工程类的指针。

 返回值 Null 参数 pPro [in]工程类的指针。

 GetSe ndTimes nt CDevName1::GetSe ndTimes(PPACKET pPac) 类型

 Public 目的 获取与设备一次交互的次数。

 返回值 一个整型数据。

 参数 pPac [in,out]包指针 GetSe ndStri ng BOOL CDev::GetSe ndStri ng(PPACKET pPac,i nt& iLe n, i nt& iRecLe n, int Times) 类型 Public 目的 根据协议组合成发送桢。

 返回值 成功返回 TRUE,否则返回 FALSE 。

 参数 pPac [in,out]指向 PACKET 结构的指针。

 iLe n [out]发送数据的长度。

 iRecLen [out]需要接收的数据的长度。

 iTimes [in]在一次发送过程中调用的次序。

 Tran smissi on BOOL CDev::Tra nsmissio n (int iLe n, int iExpectedLe n, int& iRecLe n) 类型 Public

 目的 通讯处理函数。

 返回值 成功返回 TRUE,否则返回 FALSE 。

 参数 iLe n [in]数据的长度 iExpectedLe n [in,out]期望接收到数据的长度。

 iRecLen [in,out]实际接收到数据的长度 GetFirstFrame BOOL CDev::GetFirstFrame (int n byteRead, i nt nExpectedLe n, BYTE chFrameHead) 类型 Public 目的 获取第一个正确的数据桢。

 返回值 成功返回 TURE,否则,返回 FALSE 。

 参数 n byteRead [in] 实际接收到的数据的长度。

 iExpectedLe n [in] 期望接收到的数据的长度。

 chFrameHead [in] 第一个正确数据桢的位置。

 PreProcessData BOOL CDev::PreProcessData (PPACKET pPac, i nt n byteRead ,i nt n ExpectedLe n, int iTimes) 类型

 Public 目的 检查接收的数据。

 返回值 成功返回 TURE,否则,返回 FALSE。

 参数 pPac [in,out]包指针。

 n byteRead [in]实际接收到的数据长度。

 iExpectedLe n

 8.3.1 串口通讯类 CSerialCom [in]期望接收到的数据长度。

 Sen dDataToK in gView BOOL CDev::Se ndDataToKi ngView(PPACKET pPac, i nt iLe n) 类型 Public 目的 向组态王传送数据。

 返回值 成功返回 TRUE,否则 , 返回 FALSE 。

 参数 pPac [in,out]包指针。

 iLe n [Out]接收到的数据长度。

 8.3 通讯类(CCom) 实现串口 , 网卡等的通讯 , 开发包向导会根据您的设置 , 自动地产生串口通讯类 (CSerialCom) 或者网络通讯类 ( CNetCom), 您也可以根据需要添加 USB 通讯类 (CUSBCom) 。

 如下是串口通讯类 ( CSerialCom) 结构 :

 CSerialCom ^mJwTimeOut ^bUseModem ^OpenComQ ^ClaseComQ ^ReOpenComQ ^PhysicaiSendQ ^PhysicalRecenreQ 属性 :

 DWORD m_dwTimeOut; 通讯超时变量 HANDLE m_hComm;

 串口句柄 bool bUseModem; 是否使用 MODEM 操作 :

 Open Com BOOL Ope nCom(co nst ComDevice &In itData); 类型 Public 目的 打开串口。

 返回值 成功返回 TRUE,否则返回 FALSE 。

 参数 pcc [in] ComDevice 结构指针 CloseCom BOOL CloseCom(); 类型 Public 目的 关闭串口 返回值 成功返回 TRUE,否则返回 FALSE 。

 参数 Null ReOpenCom BOOL ReOpe nCom(); 类型 Public 目的 重新打开串口。

 返回值 成功返回 TRUE,否则返回 FALSE 参数 Null

 PhysicalSe nd BOOL PhysicalSe nd(BYTE*pbBuf, DWORD dwWriteLe n); 类型 Public 目的 向串口发送一数据桢。

 返回值 成功返回 TRUE,否则返回 FALSE 。

 参数 pbBuf [in]发送数据缓冲区指针 dwWriteLe n [in]发送数据长度 PhysicalReceive BOOL PhysicalReceive(BYTE*pbBuf,i nt iStart, i nt& iBytesRead); 类型 Public 目的 从串口接收数据。

 返回值 成功返回 TRUE,否则返回 FALSE 。

 参数 pbBuf [in]接收缓冲区指针 iBytesRead [in]接收到的数据长度 8.4 调试信息类 (CDebug) 该类实现各种 调试信息在组态王信息窗口中的输出 ,比如错误信息,接口信息,数 据信息等。

 I 20U6/O8/M 2006/06/29 2006/08/29 2006/08/29 20M/W/29 2006/OE/29 20Q6/O8/M 2006/06/29 2006/06/29 2006/08/29 | 2006/06/29 13.40.51. 437 13:40:51.502 13:40:51.518 13.40.51.534 13-40-51 549 13 40:51 549 13.40:54.370 13 40:54 370 13 40:54.385 13:40:54.401 13 40:54 401

 CDebug ^>bShowlMPMsg ^bShowERRMsg ^bSho^FUNMsg 毎b S h owDATAM s g ^bShowUSERMsg 毎 b S h owALLM s g ^ShowImpMessageQ ^ShowErroMessageQ ^ShowFunMessageO ^ShowDataMessageQ ^ShowUserMessageQ 目前提供了如下信息输出标志 /IMP_MSG // 输出接口函数 /FUN_MSG // 输出功能函数 /DATA_MSG // 输出发送接收数据 /ERR_MSG // 输出错误信息 /USER_MSG // 输出用户定义信息 /ALL MSG // 输出所有信息

 当用户在设备地址处,输入如上信息,将会在组态王信息窗口中输出相应的信息。

 例如,输入 1 /ALL_MSG 在组态王信息窗口中显示: 19804303. 58663 Tht co* n 砒 h 也化 19634319 70069 CS»rialCoi* : Fhysi calRac^iv* 19884332. 11595 The con not have data! 19884343. 02Q71 CSerialCqa. : Fhysic^lAcain 1963435? 3B016 CDtvN^el 19884367. 93810 Ctl&vNanel: : SendD&taToKiTigVi ew 19887196. 9B706 CT*«tlPro..Pract£sP&ck»t2 19037107 T90T3 CD»vN wt l:: Fr«ctssF«ckt1.2 1988T208.43850 CDevNamel FrocessPacketZ 19687218. 88061 CD&1. : G^tSendStrine 19387229 17605 CDtvN^el Truis>ission 信息格式 :

 时间 精确时钟计数 信息 属性: static bool bShowIMPMsg; 输出接口信息标志 static bool bShowERRMsg; 输出错误信息标志 static bool bShowFUNMsg; 输出功能函数标志 static bool bShowDATAMsg; 输出发送接收数据标志 static bool bShowUSERMsg; 输出自定义信息标志 static bool bShowALLMsg; 输出所有信息标志 Operations : ShowImpMessage void CDebug::ShowlmpMessage(TCHAR* szMessage) 类型

 Public 目的 输出接口信息标志。

 返回值 Null 参数 szMessage [in] 显示信息 ShowErroMessage void CDebug::ShowErroMessage(TCHAR* szMessage) 类型 Public 目的 输出错误信息。

 返回值 Null 参数 szMessage [in] 显示信息 ShowF unM essage void CDebug::ShowFu nM essage(TCHAR* szMessage) 类型 Public 目的 输出功能函数信息。

 返回值 Null 参数 szMessage [in] 显示信息 ShowDataMessage void CDebug::ShowDataMessage(TCHAR* szMessage) 类型 Public 目的 输出发送接收数据信息。

 返回值 Null

 参数 szMessage [in] 显示信息 ShowUserMessage void CDebug::ShowUserMessage(TCHAR* szMessage) 类型 Public 目的 输出自定义信息。

 返回值 Null 参数 szMessage [in] 显示信息 8.5 帮助函数类(CHelper) 提供了一系列您 在开发驱动过程中可能会用到的功能函数 CHelper ^GetWordQ ^GetLongQ ^WordToBcdQ ^LongToBcdQ ^BcdToWordQ ""BcdToLongQ ■^SwapWordQ ■^SwapLongQ ^ByteBufToFloatQ ^FIoatToByteBuiQ ^ByteToAS^Q ^ASCToByteQ <>WorclToASCdO ^ASCToWordQ ^LongToAS"GO ■^ASCTo Longfl OBCDToASCQ ^ASCToBfeDQ ^KyGetTickODuntO ^Ki/JGoFileTimeNowO ^kyGlobalAddAtomQ ^KvGlobalGetAtomNameO ^KvGlobalDeleteAtomQ 操作 :

 GetWord WORD CHelper::GetWord(BYTE* buf) 类型 Public 目的 从缓冲区中得到整数 返回值 转换后的整数 • 参数 buf [in] 数据缓冲区的指针 GetL ong long CHelper::GetL on g(BYTE* buf) 类型

 Public 目的 从缓冲区中得到长整数。

 返回值 转换后的长整数 参数 buf [in] 数据缓冲区的指针 WordToBcd 类型 Public 目的 把整数转换 BCD 码。

 返回值 转换后的 BCD 码 参数 value [in] 要转换的整数 • Lon gToBcd long CHelper::L on gToBcd(lo ng value) 类型 Public 目的 把长整数转换 BCD 码。

 返回值 转换后的 BCD 码 参数 value [in] 要转换的长整数 BcdToWord

  类型 Public 目的 把 BCD 码转换整数。

 返回值

 转换后的整数 参数 value [in] 要转换的 BCD 码 BcdToL ong long CHelper::BcdToL on g(lo ng value) 类型 Public 目的 把 BCD 码转换长整数。

 返回值 转换后的长整数 参数 value [in] 要转换的 BCD 码 SwapWord

  类型 Public 目的 转换整数的高低位字节 返回值 转换后的长整数 参数 value [in] 要转换的 BCD 码 SwapLong long CHelper::SwapLo ng(WORD *value) 类型 Public 目的 转换整数的高低位字节。

 返回值 转换后的长整数 参数 value [in] 要转换的 BCD 码

 ByteBufToFloat 类型 Public 目的 把 4 个字节的数据按照 mode 转换为浮点数 FLOAT 。

 返回值 转换后的浮点数 参数 value [in] 数据缓冲区的指针 mode [in] 数据转换的模式 0 --3210 1 --2301 2 --0123 3 --1032 FloatToByteBuf void CHelper::FloatToByteBuf(BYTE *buf,float data,int mode) 类型 Public 目的 把浮点数 FLOAT 按照 mode 转换为 4 个字节的数据。

 返回值 NA 参数 buf [out] 数据缓冲区的指针 . data [in] 要转换的浮点数 mode [in] 数据转换的模式 0 --3210 1 --2301

 2 --0123 3 --1032 ByteToASC void CHelper::ByteToASC( BYTE* buf, BYTE data ) 类型 Public 目的 把一个字节的数据转换为两个 ASCII 码放在 buf 内 。

 返回值 NA 参数 buf [out] 数据缓冲区的指针 . data [out] 要转换的字节数 ASCToByte BYTE CHelper::ASCToByte( BYTE* buf ) 类型 Public 目的 把缓冲区中的两个 ASCII 码转换为一个字节数据 。

 返回值 转换后的字节数据 参数 buf [in] 数据缓冲区的指针 WordToASC void CHelper::WordToASC( BYTE* buf, WORD data ) 类型 Public 目的 把一个字的数据转换为 4 个 ASCII 码放在 buf 内 。

 返回值 Null 参数 buf [out] 数据缓冲区的指针 data

 [in] 要转换的整数 ASCToWord WORD CHelper::ASCToWord( BYTE* buf ) 类型 Public 目的 把缓冲区中的 4 个 ASCII 码转换为一个字数据。

 返回值 转换后的整数 参数 buf [in] 数据缓冲区的指针 Lon gToASC void CHelper:: LongToASC (BYTE *buf ,long data) 类型 Public 目的 把一个双字的数据转换为 8 个 ASCII 码放在 buf 内。

 返回值 Null 参数 buf [out] 数据缓冲区的指针 data [in] 要转换的长整数 ASCToLo ng LONG CHelper:: ASCToLong (BYTE *buf) 类型 Public 目的 把缓冲区中的 8 个 ASCII 码转换为一个双字数据。

 返回值 转换后的长整数 参数 buf [in] 数据缓冲区的指针 BCDToASC

 void CHelper::BCDToASC( BYTE* buf, WORD data ) 类型 Public 目的 把一个字 BCD 的数据转换为 4 个 ASCII 码放在 buf 内 。

 返回值 Null 参数 buf [out] 数据缓冲区的指针 data [in] 要转换的整数 ASCToBCD WORD CHelper::ASCToBCD( BYTE* buf ) 类型 Public 目的 把缓冲区中的 4 个 ASCII 码转换为一个字 BCD 数据。

 返回值 转换后的整数 参数 buf [in] 数据缓冲区的指针 KvGetTickCou nt ULONGLONG CHelper::KvGetTickCou nt() 类型 Public 目的 获得当前的时钟计数 返回值 一个 longlong 数 . 参数 Null KvCoFileTimeNow

 void CHelper::KvCoFileTimeNow(FILETIME *lpFileTime) 类型 Public 目的 设置时间戳 返回值 Null 参数 lpFileTime [out] FILETIME 变量指针 KvGlobalAddAtom

  类型 Public 目的 增加全局原子变量。

 返回值 一个原子变量 参数 lpStri ng [in] 要增加为原子的字符串 KvGlobalGetAtomName UINT CHelper::KvGlobalGetAtomName(STR pAtom, LPTSTR IpBuffer, i nt n Size) 类型 Public 目的 获得全局原子对应的字符串。

 返回值 字符串的长度 参数 pAtom [in] 原子指针 lpBuffer [out] 缓冲区的长度 n Size [in] 缓冲区大小 KvGlobalDeleteAtom

 STR CHelper::KvGlobalDeleteAtom(STR pAtom) 类型 Public 目的 删除原子。

 返回值 删除的原子变量 参数 pAtom [in] 要删除的原子指针 8.6 数据桢校验类 ( CCheck) 提供了在开发中会遇到的各种校验函数, 包括和校验、异或校验、循环冗 余校验等。

 CCheck ^XorCheckf) ^Sum_Check() ^LRC^CheckQ *CRCT6_CHECK0 *CRC16,CHEC K_REVERSEQ • MO DBUS CRC J CHEC KQ 操作 :

 Xor Check BYTE CCheck::Xor Check(BYTE *buf, i nt nLe n) 类型 Public 目的 异或校验。

 返回值 一个字节的数据 参数 buf [in] 数据缓冲区的指针 nLen [in] 数据缓冲区的长度 Sum_Check BYTE CCheck::Sum_Check(BYTE *buf, i nt nLe n) 类型 Public 目的

 把缓冲区中的数据按字节计算取 8 位累加和。

 返回值 一个字节数据 参数 buf [in] 数据缓冲区的指针 nLen [in] 数据长度 LRC Check BYTE CCheck::LRC Check(BYTE *buf, i nt nLe n) 类型 Public 目的 把缓冲区中的数据按字节计算累加和取反加 1。

 返回值 一个字节数据 参数 buf [in] 数据缓冲区的指针 nLen [in] 数据长度 CRC16 CHECK WORD CCheck::CRC16 CHECK(BYTE *buf, i nt nLe n) 类型 Public 目的 把缓冲区中的数据按字节计算 CRC_16(循环冗余校验 ) 。

 返回值 一个 WORD 类型数据 参数 buf [in] 数据缓冲区的指针 nLen

 [in] 数据长度 CRC16_CHECK_REVERSE WORD CCheck::CRC16 CHECK REVERSE(BYTE *buf, i nt nLe n) 类型 Public 目的 反向的 16 位循环冗余校验。

 返回值 一个 WORD 类型数据 参数 buf [in] 数据缓冲区的指针 nLen [in] 数据长度 MODBUS CRC CHECK WROD CCheck::MODBUS CRC CHECK(BYTE *buf, i nt nLe n) 类型 Public 目的 Modbus 协议的循环冗余校验 返回值 一个 WORD 类型数据 参数 buf [in] 数据缓冲区的指针 nLen [in] 数据长度 9. 错误提示信息码 驱动包含如下的 错误提示信息码 ,这些信息在资源文件 “StringResource.dll ”中定义,运行时被组态王调用。

 关于调用过程,参见函数 GetLastError 。

 (1) .常用错误提示信息码 (a) . 设备地址 #define ERR_DEVICE_ADDR_FORMAT 11 提示信息 : 设备地址格式错,请参阅帮助文档 (b) . 寄存器 #define ERR_REGISTER_NAME 12 提示信息 : 寄存器名称错误,请参阅帮助文档 #defineERR_REGISTER_DATA 类型 13 提示信息 : 寄存器数据类型错误,请参阅帮助文档 #defineERR_REGISTER_NO 14 提示信息 : 寄存器序号错误,请参阅帮助文档 #defineERR_REGISTER_FORMAT 15 提示信息 : 寄存器格式错误,请参阅帮助文档 (2) . 详细错误提示信息码 (a). 设备地址 #define ERR_DEVICE_ADDR_NEED_NUM 20 提示信息 : 设备地址必须是数字 #define ERR_DEVICE_ADDR_NEED_HEX 21 提示信息 : 设备地址必须是十六进制 #define ERR_DEVICE_ADDR_LOWFLOW 22 提示信息 : 设备地址太小 #defineERR_DEVICE_ADDR_OVERFLOW 23 提示信息 : 设备地址太大 #defineERR_DEVICE_ADDR_FILEPATH 24 提示信息 : 设备地址应为文件路径 #defineERR_DEVICE_ADDR_IP_PORT 25 提示信息 : 设备地址应为“P 地址:端口号” #defineERR_DEVICE_ADDR_IP 26

 提示信息 : 设备地址 (IP) 错误 #defineERR_DEVICE_ADDR_DATASOURCE 27 提示信息 : 设备地址应为“地址:数据源” #defineERR_DEVICE_ADDR_PASSWORD 28 提示信息 : 设备地址应为“地址:密码” #defineERR_DEVICE_ADDR_SPECIAL 29 提示信息 : 特殊设备地址格式,请参阅帮文挡 (b). 寄存器通道 #defineERR_REGISTER_SPILTTER_CHAR 40 提示信息 : 通道号分隔符应该为 "." #defineERR_REGISTER_CH1 41 提示信息 :

 42 43 类型 BIT 60 #defineERR_REGISTER_DATA 类型 _BYTE 61 #defineERR_REGISTER_DATA 类型 _SHORT 62

 #defineERR_REGISTER_CH2 提示信息 : 寄存器应有二级序号,请参阅帮助文档 #defineERR_REGISTER_CH3 提示信息 : 寄存器应有三级序号,请参阅帮助文档 #defineERR_REGISTER_CH1_LOWFLOW 44 提示信息 : 寄存器 1 级序号超下限,请参阅帮助文档 #defineERR_REGISTER_CH1_OVERFLOW 45 提示信息 : 寄存器 1 级序号超上限,请参阅帮助文档 #defineERR_REGISTER_CH2_LOWFLOW 46 提示信息 : 寄存器 2 级序号超下限,请参阅帮助文档 #defineERR_REGISTER_CH2_OVERFLOW 47 提示信息 : 寄存器 2 级序号超上限,请参阅帮助文档 #defineERR_REGISTER_CH3_LOWFLOW 48 提示信息 : 寄存器 3 级序号超下限,请参阅帮助文档 #defineERR_REGISTER_CH3_OVERFLOW 49 提示信息 : 寄存器 3 级序号超上限,请参阅帮助文档 (c).寄存器数据类型 #defineERR_REGISTER_DATA 提示信息 : 寄存器仅支持 BIT 数据类型

 提示信息 : 寄存器仅支持 BYTE 数据类型

  请参阅帮助文档

 提示信息 : 寄存器仅支持 SHORT 数据类型

 寄存器仅支持 LONGBCD 数据类型 #defi neERR_REGISTER_DATA 类型 _FLOAT 67 提示信息 : 寄存器仅支持 FLOAT 数据类型 #defi neERR_REGISTER_DATA 类型 _STRING 68 提示信息 : 寄存器仅支持 STRING 数据类型 (3)

 . 2007 年 1 月份新增设备地址和寄存器提示信息的使用办法 ( 1 )

 . 输入描述:

 设备地址越限 提示信息:

 设备地址范围越限,请参阅帮助文档 适用范围:

 只有一个域的简单地址格式,值越限的情况 错误 ID :

 ERR_ADDR_EXCEED ( 2 )

 . 输入描述:

 输入非法的地址或者地址格式错误 提示信息:

 设备地址格式错误,请参阅帮助文档 适用范围:

 除 1 以外的其他地址格式错误 错误 ID :

 ERR_ADDR_FORMAT ( 3 )

 . 输入描述:

 寄存器名称错误 提示信息:

 寄存器名称错误,请从寄存器列表中选择寄存器或参阅帮助文档 使用范围:

 所有类型的寄存器 错误 ID :

 ERR_REG_NAME ( 4 )

 . 输入描述:

 寄存器通道号越限 提示信息:

 寄存器通道号越限,请参阅帮助文档

 #defineERR_REGISTER_DATA 提示信息 : 寄存器仅支持 UINT 数据类型 #defineERR_REGISTER_DATA 提示信息 : 寄存器仅支持 BCD 数据类型 #defineERR_REGISTER_DATA 提示信息 : 寄存器仅支持 LONG 数据类型 #defineERR_REGISTER_DATA 提示信息 : 类型 _USHORT 63 类型 _BCD 64 类型 _LONG 65 类型 _LONGBCD66

 +罗克韦尔 所遴设备 生产厂彖:莫迪噩 设备 E 称:Modfcus 腆丈阴〕 遇信茹述:卿爭 使用范围:

 只用一级通道的简单寄存器,通道号范围越...

相关热词搜索: 程序开发 驱动 组态王