HART实用命令详解
- 格式:pdf
- 大小:174.71 KB
- 文档页数:11
目录§1.HART协议智能变送器技术简介§2.兴业达HART协议智能变送器简介§3.基于PC的HART协议智能变送器管理系统§4.电路连接§5.用个人电脑管理HART协议智能变送器§6.用HART协议手操器管理HART协议智能变送器§7.现场调零与报警输出附录一、兴业达智能变送器HART协议命令一览表附录二:兴业达HART协议智能变送器性能参数本公司产品适用于下列产品的智能化设计:金属浮子流量计(配M7/M9指示器)1151电容式压力变送器温度变送器(Pt100,Cu50,各型号热电偶)称重式浮筒液位变送器91系列投入式压力变送器/深度液位计2390电动浮筒液位变送器电动内浮球液位变送器§1.HART协议智能变送器技术简介§1.1 工业自动化行业的大趋势---现场总线现场总线就是数字通讯一直延伸到现场仪表,使变送器、调节阀、记录仪、显示器、PLC及其它自动化设备等可通过一条总线进行双向多信息数字通讯,从而取代目前使用的4~20mA单变量单向模拟传输方式。
现场总线技术是在市场对现场仪表智能化以及全数字控制系统的需求驱动下产生的。
从技术的角度看,则是计算机技术、网络技术和控制技术发展的必然产物。
现场总线的关键标志是它能支持双向、多变量、总线式的全数字通信。
现场总线技术的出现,必将冲击现有过程控制系统的技术知识、设计方法、安装调试方法、人员培训以及产品市场的格局。
为了在这次变革中不至于被抛在后面,不同国家、不同厂商纷纷组成集团,发表各自的现场总线标准,以图率先占领市场。
比较主要的现场总线标准有Profitbus、CAN、Lonworks、SP50、ISPFIP和HART等,但由于受各自利益驱动和市场竞争,现场总线国际标准的制定进展缓慢。
§1.2 HART协议的发展虽然现场总线发展迅速,但由于4~20mA信号制的模拟设备还在大量使用中,因此从4~20mADC信号转变为现场总线全数字通讯并非一蹴而就,预计这一转变需要几十年时间。
操作说明1.显示屏格式显示屏分为4个功能显示区第一区:流量、压力、温度指示区,Q、P第二区:电池电量显示区,右侧进程条第三区:瞬时流量显示区,上一排6位数字,小数点可以浮动显示第四区:累积流量显示区,下一排8位数字,小数点固定两位小数显示显示单位之一:瞬时流量M3/h,累积流量M3显示单位之二:瞬时流量L/h,累积流量L2.键盘操作显示窗口如图示按键为4键式:“Ent”、“→”、“↑”、“Esc”。
“Ent”: 翻页浏览键、修改确认存储键(存在差异时存储)“Esc”:无修改退出,修改错误退出“→”:移位键“↑”:数字增加键修改操作:操作“→”移位键时,对应数字位将闪动,可以用“↑”修改。
第一屏:常显显示屏,无单位指示,由功能选项决定单位是M3或L 第一行显示瞬时流量,小数点浮动显示第二行显示累积流量,两位小数显示右侧为电池电量指示第二屏:其它显示项,第一行显示电池电压,一位小数,显示模式“U x.x”。
进程条显示:≥3V显示S1-S14;2.3V-3V之间,0.05V一个显示块。
第二行显示信号频率,一位小数,显示模式“F x.x”右侧为电池电量指示第三屏:参数设置第一行无显示。
第二行显示“- - - -”输入密码①输入四位密码“1234”:浏览并可以修改用户设置参数;②输入四位密码“5678”:存储为出厂设置;③输入四位密码“1111”:恢复出厂设置;④不输入密码或输入密码不正确:浏览但不可以修改用户设置参数。
密码正确,确认键生效,显示正确存储提示“oooo”;再次确认时:①进入第四屏,开始浏览并可以修改用户设置参数,②③退出至常显屏,④进入第四屏,开始浏览但不可以修改用户设置参数,退出键退出。
退出键无操作。
注释:设置密码的目的,是为了防止错误修改用户设置参数、错误存储出厂设置和错误恢复出厂设置。
第四屏:显示补偿系数单位第一行显示功能代码01第二行显示补偿系数单位:1:输入M3系数,显示M3流量2:输入L系数,显示L流量3:输入L系数,显示M3流量(此选项是为需要显示M3流量,但M3系数过大的情况而设置,用“↑”可以选定,流量显示实时换算,换算为“升”时,只显示8位有效数字,其余高位只存储,不显示)4:输入L系数,显示L/min流量第五屏:显示阻尼时间第一行显示功能代码02第二行显示阻尼时间,单位为“秒”,1-10秒第六屏:显示仪表的最大流量第一行显示功能代码03第二行显示最大流量(8位)无单位指示,由功能选项决定单位是M3或L精确度为0.01 M3/h或0.01L/h精确度第七屏:显示仪表的最小流量(小信号切除流量)第一行显示功能代码04第二行显示最小流量(8位)无单位指示,由功能选项决定单位是M3或L精确度为0.01 M3/h或0.01L/h精确度第八屏:显示仪表的输出频率上限第一行显示功能代码05第二行显示频率上限0-3000Hz,精确度为0.1Hz第九屏:仪表地址第一行显示功能代码06第二行显示仪表地址:0-15第十屏:累积量设置(包含清零功能)第一行显示功能代码07第二行显示当前累积流量(不实时刷新),可以修改为任意值(单位与累积流量显示相同),精确两位小数。
MAN 4275A00PN: 00275-8026-0001简体中文二零零四年九月HART®手操器Fisher-Rosemount TM编译:**************HART手操器操作手册注意事项:在使用该产品工作之前请通读了这本手册。
为了个人和系统安全, 以及最恰当的产品使用,确定在使用或修护前彻底地了解该产品。
如果有设备服务需要,请连络最近的产品代表。
Rosemount 和SMART FAMILY 是 Rosemount 公司的注册商标MINIGRABBER 是的Pomona Electronics一个商标。
HART是HART通信基础公司的一个注册的商标。
Fisher-Rosemount8301 Cameron 路Austin,TX 78754 美国技术支持: 1-800-833-8314或 (512)832-3774服务热线: 1-800-654-7768 Fisher-Rosemount TM Fisher- Rosemount 系统公司 2000.版权所有。
HART手操器.....................................1-1介绍.............................................1-1hart 手操器连接..................................1-2液晶显示 (LCD)...................................1-5动作键...........................................1-5ON/OFF 键........................................1-5上箭头键.........................................1-6下箭头键............................…….........1-6左箭头键和预设菜单键.............……………......1-6右箭头和选择键....................……….…......1-6热键.............................…..............1-6软件定义功能键................……………….......1-6字母键和 Shift 键................…………........1-8使用快速选择功能..................…………….....1-8使用 Shift 键输入数据...............……….......1-9开始了解HART手操器..........………………………...1-9软件图标...................………...............1-10学习菜单结构...............……………….........1-11回顾安装的装置..................…………........1-12主要菜单........................................1-12脱机菜单........................................1-13新配置(脱机)....................……………......1-14从空白的模板菜单...............………...........1-15已存档配置菜单(脱机)..............…………......1-17数据包内容菜单...................………….......1-17已存档配置菜单 (数据包内容)..………………….....1-18联机菜单..........................…............1-19频率配置菜单........................……........1-22公用程式菜单....................................1-22手操器配置菜单..................………………....1-22轮询菜单..............................……......1-23对比度菜单......................................1-24关闭时间菜单....................................1-24i忽略诊断菜单....................................1-25 删除配置菜单....................................1-25 系统信息菜单........................... . . . ...1-26 计算机接收菜单.........................….......1-26 储存位置菜单.......................... .. .......1-28 仿真菜单................................ .......1-28 储存被连接的设备配置..........…………………....1-29 使用热键.....................……...............1-30 自定义热键菜单 .................…………........1-31 在热键菜单增加选项...............…………….....1-31 删除热键菜单选项...........…………………….....1-33 HART 手操器和 2000 年问题........…………….....1-34 编辑日期.........................……...........1-34 HART手操器修护..................………………....1-35 HART 手操器校正...............………………......1-35 使用电池组.......................……...........1-35 更换碱性电池......................……………....1-36 可充电电池组....................………………....1-37 使用存储模块......................………........1-37 更换存储模块...................……………….....1-38 安装和删除数据包装 100........……………………..1-39 Fisher- Rosemount Hart手操器通用任务................…..…..……....2-1 介绍................................…….........2-1 上电联机..............................……….....2-1 Online Menu(联机菜单).....................…....2-2 Device Setup(设备设定)..........................2-2 Primary Variable(测量值 PV)......................2-3 Analog Output(模拟输出 AO).......................2-3 Lower Range Value 量程下限 (LRV)..................2-3 Upper Range Value 量程上限 (URV)..................2-3 Device Setup Menu(设备设定菜单)...................2-4 Process Variables(过程变量)......................2-4 Process Variables(诊断/服务)....................2-4 Basic Setup(基本设定)..........................2-5 Detailed Setup(详细的设定).......................2-5ii回顾.............................................2-6 快速键顺序...............................……....2-6菜单树..........................................3-1 介绍.............................................3-1 1151 压力变送器..................................3-2 3051C 压力变送器 (独创的)............….…….....3-3 9739 质量流量计......................…..........3-4附录A HART手操器信息.........................A-1 附录B 规格和订货信息…………………….……..B-1附录C CSA和FM本质安全认证………………………..C-1 附录D手操器故障处理…………………………….D-1 附录E 索引及解释…………………………………E-1iii例证列表序号名称页码1-1. HART 手操器 ................................1-1 1-2. 可充电镍铬电池联结面板 ...........…......1-21-3. 连接到变送器通讯终 ..............….........1-3 1-4. 回路中HART 手操器的连接 ............…......1-3 1-5. 用负载电阻连接 HART 手操器…………………….1-4 1-6. HART手操器字母键和Shift 键 ........….......1-8 1-7. 快速访问菜单 .....................…........1-8 1-8. 通电脱机或联机......................….....1-10 1-9. 菜单图标和相关键...........................1-10 1-10. 主要菜单...........................….....1-12 1-11. 脱机菜单树................................1-13 1-12. 脱机菜单..................................1-14 1-13. 从空白模板菜单............................1-15 1-14. 个人编辑菜单..............................1-15 1-15. 单元变量菜单..............................1-15 1-16. 保存菜单...........................……...1-16 1-17. 定位菜单..................................1-16 1-18. 配置保存菜单 (脱机) .....................1-17 1-19. 数据包内容菜单............................1-17 1-20. 配置保存菜单 (数据包) ......…......1-181-21. 联机菜单............................…....1-19 1-22. 通用联机菜单树.....................……...1-21 1-23. 频率设置菜单.......................….....1-22 1-24. 公用程序菜单........................…....1-22 1-25. 手操器设置菜单...................…….....1-22 1-26. 轮询菜单............................…....1-23 1-27. 对比度菜单..........................…....1-24 1-28. 关机时间菜单.........................…...1-24 1-29. 忽略诊断菜单.................……………...1-25iv1-30. 删除配置菜单 . ...........................1-25 1-31. 系统信息菜单.............………...........1-26 1-32. 计算机接收菜单… .........................1-26 1-33. 储存位置菜单................………........1-28 1-34. 热键标本菜单.................….....…....1-30 1-35. 热键配置菜单.. ........... .....…….......1-31 1-36. 增加热键选择项.. .... ........... ........1-32 1-37. 标记只读热键选择项… .......... ..........1-32 1-38. 热键菜单.. .......……………… . ........1-32 1-39. 变量显示设置选择项 ............. .. ......1-33 1-40.删除热键选择项 ........……………..… ....1-33 1-41. 日期菜单………….. .......................1-34 1-42. HART 手操器防爆检查…………….. .........1-35 1-43. 电池组拆卸 .....………...... .............1-36 1-44. 存储模块更换……………….. ........... ...1-38 1-45. 数据包装 100个安装和卸载……… ...... ....1-39 2-1. 联机菜单………………………….. ..... .......2-2 2-2. 设备设定菜单……. .... ......................2-4 2-3. 诊断和服务菜单…………………….. ..... .....2-4 2-4. 基本设定菜单………………….. ........ ..... .2-5 2-5. 快速键顺序样本………………… ..... .........2-6表列表序号名称页码1-1. 功能键标识..................................1-7 1-2. PC AMS 界面主要选择项......……………...........1-27vHART® 手操器概述 HART(Highway Addressable Remote Transducer 高速可寻址遥远的转换器)手操器(图 1-1)是手持式设备,提供了联接到所有的HART-相容基于微处理的仪器设备的通用通讯。
HART375操作说明操作说明1. 引言本操作说明旨在提供关于HART375产品的使用指南和详细的操作步骤。
2. 产品概述HART375是一款高精度的测量仪器,可用于测量和监测各种流体的压力、温度和液位等参数。
3. 产品特点- 高精度测量- 多种参数测量功能- 简单易用的操作界面- 可靠的数据传输4. 系统要求在使用HART375之前,请确保满足以下系统要求:- 操作系统:Windows 7或更高版本- USB接口- 相应的传感器和设备5. 安装步骤5.1 连接设备1. 将HART375通过USB线缆连接到计算机。
2. 将传感器与HART375连接,并确保连接牢固稳定。
5.2 软件安装1. 将附带的安装光盘插入计算机光驱。
2. 打开安装程序,并按照屏幕上的指示进行安装。
3. 完成安装后,在计算机上找到安装的软件图标并运行。
6. 使用指南6.1 设备启动与关闭1. 将HART375插入电源适配器,并将适配器插入电源插座。
2. 按下开/关按钮启动HART375。
3. 长按开/关按钮可以关闭HART375。
6.2 参数测量设置1. 在主界面上选择所需的参数类型。
2. 使用菜单键进入参数设置界面。
3. 根据需要设置相关参数,包括单位、精度等。
6.3 数据记录与导出1. 在参数测量界面上按下记录按钮开始记录数据。
2. 数据记录完成后,可以选择导出数据到计算机或其他外部设备。
3. 通过USB连接将HART375和计算机连接起来。
4. 在计算机上打开数据导出软件,并按照软件的操作指南将数据导出到指定位置。
7. 附件本文档附带以下附件:- HART375安装光盘8. 法律名词及注释- USB:通用串行总线,一种用于计算机与外部设备进行通信的标准接口。
- 精度:测量结果与真实值之间的差异程度,通常用百分比表示。
Universal Command SpecificationHCF_SPEC-127, Revision 6.0 Release Date: 18 April, 2001HART Communication Foundation Document Number: HCF_SPEC-127Document Title: Universal Command SpecificationRevision 6.0, Release Date: 18 April, 2001Page 2 of 44Release Date: 18 April, 2001Document Distribution / Maintenance Control / Document ApprovalTo obtain information concerning document distribution control, maintenance control and document approval, please contact the HART Communication Foundation at the address shown below.Copyright © HART Communication FoundationThis document contains copyrighted material and may not be reproduced in any fashion without the written permission of the HART Communication Foundation.Trademark InformationHART ® is a registered trademark of the HART Communication Foundation, Austin, Texas, USA.Any use of the term H ART hereafter in this document, or in any document referenced by this document, implies the registered trademark. All other trademarks used in this or referenced documents are trademarks of their respective companies. For more information contact the H CF Staff at the address below.Attention: Foundation DirectorHART Communication Foundation9390 Research BoulevardSuite I-350Austin, TX 78759, USAVoice: (512) 794-0369FAX: (512) 794-3904HART Communication Foundation Document Number: HCF_SPEC-127Document Title: Universal Command SpecificationTable of ContentsPreface (5)Introduction (7)1. Scope (9)2. References (9)2.1 The HART-Field Communications Protocol Specifications (9)2.2 Related HART Documents (9)3. Definitions (10)4. Symbols/Abbreviations (10)5. Data Format (11)6. Commands (12)6.1 Command 0 Read Unique Identifier (12)6.2 Command 1 Read Primary Variable (14)6.3 Command 2 Read Loop Current And Percent Of Range (15)6.3.1 Percent of Range (Transmitters) (15)6.3.2 Percent of Range (Actuators) (15)6.4 Command 3 Read Dynamic Variables And Loop Current (17)6.5 Command 4 Reserved (19)6.6 Command 5 Reserved (19)6.7 Command 6 Write Polling Address (20)6.7.1 Backward Compatibility Requirements (20)6.8 Command 7 Read Loop Configuration (22)6.9 Command 8 Read Dynamic Variable Classifications (23)6.10 Command 9 Read Device Variables with Status (24)6.11 Command 11 Read Unique Identifier Associated With Tag (27)6.12 Command 12 Read Message (28)6.13 Command 13 Read Tag, Descriptor, Date (29)6.14 Command 14 Read Primary Variable Transducer Information (30)6.15 Command 15 Read Device Information (31)6.15.1Write Protect Mode (31)Revision 6.0, Release Date: 18 April, 2001Page 3 of 44HART Communication Foundation Document Number: HCF_SPEC-127Document Title: Universal Command Specification6.16 Command 16 Read Final Assembly Number (33)6.17 Command 17 Write Message (34)6.18 Command 18 Write Tag, Descriptor, Date (35)6.19 Command 19 Write Final Assembly Number (37)6.20 Command 20 Read Long Tag (38)6.21 Command 21 Read Unique Identifier Associated With Long Tag (39)6.22 Command 22 Write Long Tag (40)Annex A. Revision History (41)A1. Changes from Revision 5.2 to Revision 6.0 (41)A2. Changes from Revision 5.1 to Revision 5.2 (42)A3. Changes from Revision 5.0 to Revision 5.1 (42)A4. Major Modifications from Revision 4 to Revision 5.0 - Final (44)A5. Major Modifications from Initial Revision 3 to Revision 4 (44)Revision 6.0, Release Date: 18 April, 2001Page 4 of 44HART Communication Foundation Document Number: HCF_SPEC-127Document Title: Universal Command SpecificationRevision 6.0, Release Date: 18 April, 2001Page 5 of 44PrefaceThis preface is included for informational purposes only.H ART 6 is the first major revision to the Protocol in nearly 10 years. H owever, developers,manufacturers and users of the HART compatible devices can be assured that fundamental HART principles are maintained. H ART 6 is backward compatible with H ART 5 while increasing the capabilities of 4-20mA devices and systems. New commands have been added, and bytes added to several commands. HART 5 masters should work with HART 6 slaves and vice versa. Obviously,the H ART 5 master cannot take advantage of H ART 6 features, but an immediate wholesale replacement of control systems and field devices is not the objective of the Protocol. For example,an older I/O system that supports only 25Byte H ART Commands cannot issue the 32Byte Long Tag Commands.In this specification six new commands have been added and bytes are added to several commands:1. Three new commands support a new 32 byte, ISO Latin-1 Long Tag. The commands readand write the Long Tag and an Identity Command supports polling via the Long Tag.Identity Commands and their use is explained in the Command Summary Specification.2. Two bytes are added to the Identity Commands indicating the number of response preamblesand the number of Device Variables. The number of Device Variables has long been desiredby master applications.3. Polling address support is enhanced. In addition, the Loop Current is now allowed to beactive at polling addresses other then zero. For example:• This allows series connections of actuators implementing a split range capability.• The increasing use of transmitters connected in series with actuators is now directly supported allowing the embedding of PID controllers in field devices.A new command is added to allow the configuration of the loop to be read.4. Cyclical data acquisition has long been an under-utilized strength of HART. Support fordigital process readings is enhanced through the addition of Command 9 which supplies astatus byte for each process reading returned. The Command Summary Specificationdescribes the function of this status byte.5. A command is added that allows the Device Variable Classification for each Dynamic Variableto be read and allows for Engineering Unit Code Expansion.These additions are valuable in many applications. H owever, the changes are incremental enhancements that do not fundamentally change the Protocol.HART Communication Foundation Document Number: HCF_SPEC-127Document Title: Universal Command SpecificationIn addition to functional changes, the document as a whole has been reformatted to include new sections: Preface, Introduction, Scope, References, Definitions, Symbols/Abbreviations, and Data Format. The additional sections and the new format improves the clarity and consistency of the Specifications.Revision 6.0, Release Date: 18 April, 2001Page 6 of 44HART Communication Foundation Document Number: HCF_SPEC-127Document Title: Universal Command SpecificationRevision 6.0, Release Date: 18 April, 2001Page 7 of 44IntroductionThe Univ ersal Command Specification is a key document in the HART Specifications as it establishes the minimum Application Layer support required of all HART Devices. In fact, the Universal Command Specification is considered so important that the major revision level of the entire Protocol always matches the major revision level of this document.H ART is a master-slave protocol and is loosely organized around the ISO/OSI 7-layer model for communications protocols (see Figure 1). The Application Layer is the topmost layer in the Open System Interconnect (OSI) model. More H ART specification documents address the ApplicationLayer than any other OSI Layer.Figure 1. OSI 7-Layer ModelThe Application Layer in HART defines the commands, responses, data types and status reporting supported by the Protocol. In addition, there are certain conventions in HART (for example how to trim the loop current) that are also considered part of the Application Layer. While the Command Summary, Common Tables and Command Response Code Specifications all establish mandatory Application Layer practices (e.g. data types, common definitions of data items, and procedures), the Universal Commands specify the minimum Application Layer content of all HART compatible devices.HART Communication Foundation Document Number: HCF_SPEC-127Document Title: Universal Command SpecificationRevision 6.0, Release Date: 18 April, 2001Page 8 of 44HART Communication Foundation Document Number: HCF_SPEC-127Document Title: Universal Command Specification1.SCOPEThis document is an Application Layer specification and, as a result, builds on the Application Layer requirements found in the Command Summary Specification. Conformance to the Universal Command Specification requires Command Summary Specification conformance as a prerequisite. This document supersedes all previous revisions of the Universal Command Specification.The Univ ersal Command Specification contains definitions of all H ART Protocol Universal Commands. HART compatible devices must implement all universal commands exactly as described within this specification. Many Universal Commands refer to tables from the Common Tables Specification. When Common Tables are referenced, data from the tables must be used exactly as specified.2.REFERENCES2.1The HART-Field Communications Protocol SpecificationsThese documents published by the H ART Communication Foundation are referenced throughout this specification:HART Field Communications Protocol Specification. HCF_SPEC-12Data Link Layer Specification. HCF_SPEC-81Command Summary Specification. HCF_SPEC-99Common Practice Command Specification. HCF_SPEC-151Common Tables Specification. HCF_SPEC-183Command Response Code Specification. HCF_SPEC-3072.2Related HART DocumentsThe H ART Protocol Specifications frequently reference the manufacturer’s device-specific document. Device-specific documents are developed and controlled by the respective manufacturer and should follow the requirements of the following HART Communication Foundation document: Field Device Specification Guide. HCF_LIT-18Revision 6.0, Release Date: 18 April, 2001Page 9 of 44HART Communication Foundation Document Number: HCF_SPEC-127Document Title: Universal Command Specification3.DEFINITIONSDefinitions for terms can be found in Communications Protocol Specification. Terms used in this document include: ASCII, Broadcast Address, Data Link Layer, Delayed Response, Delayed Response Mechanism, Device Reset, Device Variable, Busy, Dynamic Variable, Fixed Current Mode, Floating Point, ISO Latin-1, Master, Multi-drop, Not-A-Number, Packed ASCII, Preamble, Request Data Bytes, Response Data Bytes, Response Message, Slave, Slave Time-Out, Software Revision Level, Time Constant, Units Code.4.SYMBOLS/ABBREVIATIONSADC A nalog-to-D igital C onverterDAC D igital-to-A nalog C onverter.DAQ D ata A c q uisition. This refers to a devices specific ADC or DACDR D elayed R esponseHCF H ART C ommunication F oundationLRV L ower R ange V alue. Defines the relationship between a Dynamic Variable value and an analog channel lower endpoint (e.g. 4.00mA).LSB L east S ignificant B yte. The LSB is always the last byte transmitted over a HART data linkLTL L ower T ransducer L imit. The digital value that defines the minimum reliable and accurate value of a dynamic or Device VariableMSB M ost S ignificant B yte. The MSB is always the first byte transmitted over a HART data link.URV U pper R ange V alue. Defines the relationship between a Dynamic Variable value and an analog channel upper endpoint (e.g. 20.0mA).UTL U pper T ransducer L imit. The digital value that defines the maximum reliable and accurate value of a dynamic or Device VariableRevision 6.0, Release Date: 18 April, 2001Page 10 of 445.DATA FORMATIn HART Protocol command specifications, the following key words are used to refer to the data formats. For more information about these formats refer to the Command Summary Specification. Bits Each individual bit in the byte has a specific meaning. Only values specified by the command may be used. Bit 0 is the least significant bit.Date The Date consists of three 8-bit binary unsigned integers representing, respectively, the day, month, and year minus 1900. Date is transmitted day firstfollowed by the month and year bytes.Enum An integer enumeration with each numeric value having a specific meaning. Only values specified in the Common Tables Specification may be used.Float An IEEE 754 single precision floating point number. The exponent is transmitted first followed by the most significant mantissa byte.Latin-1 A string using the 8-bit ISO Latin-1 character set. Latin-1 strings are padded out with zeroes (0x00).Packed A string consisting of 6-bit alpha-numeric characters that are a subset of the ASCII character set. This allows four characters to be packed into three bytes.Packed ASCII strings are padded out with space (0x20) characters.Unsigned-nn An unsigned integer where nn indicates the number of bits in this integer. Multi-byte integers are transmitted MSB — LSB.MANDS6.1Command 0 Read Unique IdentifierThis is an Identity Command (see the Command Summary Specification).Returns identity information about the field device including: the Device Type, revision levels, and Device ID. This command is implemented by a field device in both Short and Long Frame Formats. Command 0 is the only command that may respond to a short frame address.The combination of Manufacturer ID, Device Type, and Device ID make up the Unique ID used to construct the long frame address. No two devices ever manufactured may have the same combination of these three data.The Configuration Change Counter must be incremented once for every command received that changes the devices configuration. The counter must also be incremented once for every user action that changes the device’s configuration or calibration (e.g., from a local operator interface). This value is never reset or written and must be maintained, even if power is removed from the device or a device reset is performed.Request Data BytesByte Format DescriptionNoneResponse Data BytesByte Format Description0Unsigned-8"254"1 Enum Manufacturer Identification Code (see Common Table 8,Manufacturer Identification Codes)2 Enum Device Type (refer to the Command Summary Specificationand the Data Link Layer Specification)3Unsigned-8Minimum number of Preambles required for the requestmessage from the Master to the Slave. This number includesthe two preambles used in asynchronous Physical Layers(along with the Delimiter) to detect the start of message.4Unsigned-8Universal Command Major Revision Number implementedby this device. For HART Revision 6, this value must be thenumber 6.5 Unsigned-8 Device Revision Level (refer to the Command SummarySpecification)6Unsigned-8Software Revision Level of this device. Levels 254 and 255are reserved.7Unsigned-5(Most Significant 5 Bits) H ardware Revision Level of theelectronics in this particular device. Does Not NecessarilyTrace Individual Component Changes. Level 31 is Reserved.7Enum(Least Significant 3 Bits) Physical Signaling Code (seeCommon Table 10, Physical Signaling Codes)8 Bits Flags (see Common Table 11, Flag Assignments)9-11Unsigned-24Device ID. This number must be different for every devicemanufactured with a given Manufacturer ID and DeviceType.12Unsigned-8Minimum number of preambles to be sent with the responsemessage from the slave to the master.13Unsigned-8Maximum Number of Device Variables. This indicates thelast Device Variable code that a host application shouldexpect to be found in the field device (e.g., when identifyingthe Device Variables using Command 54).14-15Unsigned-16Configuration Change Counter16Bits Extended Field Device Status (refer to Common Table 17,Extended Field Device Status)Command-Specific Response CodesCode Class Description0Success No Command-Specific Errors1-127Undefined6.2Command 1 Read Primary VariableRead the Primary Variable. The Primary Variable value is returned along with its Units Code.Request Data BytesByte Format DescriptionNoneResponse Data BytesByte Format Description0 Enum Primary Variable Units (refer to Common TablesSpecification)1-4Float Primary VariableCommand-Specific Response CodesCode Class Description0Success No Command-Specific Errors1-5Undefined6Error Device-Specific Command Error7Undefined8Warning Update Failure9-15Undefined16Error Access Restricted17-127Undefined6.3Command 2 Read Loop Current And Percent Of RangeReads the Loop Current and its associated Percent of Range. The Loop Current always matches the current that can be measured by a milli-ammeter in series with the field device. This includes the loop current under alarm conditions.6.3.1Percent of Range (Transmitters)Percent of Range always follows the Primary Variable value, even if Loop Current is in an alarm condition or set to a value. The Upper and Lower Range Values maps the Primary Variable value to the Percent of Range. Percent of Range is not limited to values between 0% and 100%, but tracks the Primary Variable to the Transducer Limits when they are defined.6.3.2Percent of Range (Actuators)Percent of Range always follows the Loop Current even if it is set to a value. The Upper and Lower Range Values map the Loop Current Value to the Percent of Range. As a result the Percent of Range is not limited to values between 0% and 100%, but tracks the Loop Current to Transducer Limits when they are defined.Request Data BytesByte Format DescriptionNoneResponse Data BytesByte Format Description0-3Float Primary Variable Loop Current (units of milli-amperes)4-7Float Primary Variable Percent of Range (units of percent) Note:Voltage Mode Field Devices use "Volts DC" as their engineering unitsCommand-Specific Response CodesCode Class Description0Success No Command-Specific Errors1-5Undefined6Error Device-Specific Command Error7Undefined8Warning Update Failure9-15Undefined16Error Access Restricted17-127Undefined6.4Command 3 Read Dynamic Variables And Loop CurrentReads the Loop Current and up to four predefined Dynamic Variables. The Loop Current always matches the current that can be measured by a milli-ammeter in series with the field device; this includes alarm conditions and set values.The Response Data is truncated after the last Dynamic Variable supported by each Device Type (see Table 1). For a given Device Type the number of Response Data bytes must be fixed. In other words, a Device type may not return PV, SV, and TV in one operating mode and later (in a different operating mode) only return PV and SV.Table mand 3 Response Based on Number of DynamicVariables Supported.Dynamic Variables Supported No. of Response DataBytesPV9PV, SV14 PV, SV, TV19 PV, SV, TV, QV24Request Data BytesByte Format DescriptionNoneResponse Data BytesByte Format Description0-3Float Primary Variable Loop Current (units of milli-amperes)4 Enum Primary Variable Units Code (refer to Common TablesSpecification)5-8Float Primary Variable9 Enum Secondary Variable Units Code (refer to Common TablesSpecification)10-13Float Secondary Variable14 Enum Tertiary Variable Units Code (refer to Common TablesSpecification)15-18Float Tertiary Variable19 Enum Quaternary Variable Units Code (refer to Common TablesSpecification)20-23Float Quaternary VariableNote Voltage Mode Field Devices use "Volts DC" as their engineering units for "Loop Current" rather then milliampsCommand-Specific Response CodesCode Class Description0Success No Command-Specific Errors1-5Undefined6Error Device-Specific Command Error7Undefined8Warning Update Failure9-15Undefined16Error Access Restricted17-127Undefined6.5Command 4 ReservedRevisions 3 and 4 of this document included this command. These commands must not be implemented in any field device.6.6Command 5 ReservedRevisions 3 and 4 of this document included this command. These commands must not be implemented in any field device.6.7Command 6 Write Polling AddressThis is a Data Link Layer Management Command.This Command writes the polling address and the loop current mode to the field device. The polling address is used for automatic master identification of field devices. The loop current mode determines whether current signaling is being used by the field device.Masters claiming compatibility with this revision of the specification must always supply the all request data bytes.All Field Devices must be able to operate in multi-drop with loop current signaling disabled. When current signaling is disabled, the loop current is set to the minimum value required for field device operation. The field device status bit 3, Loop Current Fixed, is set, and, if appropriate, the Upscale/ Downscale Alarm is disabled. Furthermore, commands that affect the Loop Current must not be executed while loop current signaling is disabled. These include:•Command 40 Enter/Exit Fixed Current Mode;•Command 45 Trim Loop Current Zero; and•Command 46 Trim Loop Current Gain.These Commands shall return Command-Specific Response Code 11, In Multidrop Mode, while loop current signaling is disabled . In addition,•Command 66 Enter/Exit Fixed Analog Output Mode;•Command 67, Trim Analog Output Zero; and•Command 68, Trim Analog Output Gainshall return Command-Specific Response Code 11, In Multidrop Mode, when Analog Channel 0 is selected and loop current signaling is disabled.All Field Devices should be manufactured with the polling address set to a default value of zero (0) and the loop current mode set to active. This ensures HART field devices will operate in place of an analog-only field device by default.6.7.1Backward Compatibility RequirementsField devices receiving Command 6 with a single data byte must: (1)assume the Master is HART Revision 5; (2)enable current signaling if the polling address is zero; (3)disable current signaling if the polling address is non-zero and (4)answer providing both the polling address in the master request and the appropriately set Loop Current Mode byte.When a field device receives a single request data byte, it must answer the master request without returning Response Code 5, Too Few Data Bytes Received.Request Data BytesByte Format Description0 Unsigned-8 Polling Address of Device (refer to the Data Link LayerSpecification)1Enum Loop Current Mode (refer to Common Table 16, LoopCurrent Modes)Response Data BytesByte Format Description0 Unsigned-8 Polling Address of Device (refer to the Data Link LayerSpecification).1Enum Loop Current Mode (refer to Common Table 16, LoopCurrent Modes)Command-Specific Response CodesCode Class Description0Success No Command-Specific Errors1Undefined2Error Invalid Poll Address Selection3-4Undefined5Error Too Few Data Bytes Received6Error Device-Specific Command Error7Error In Write Protect Mode8-11Undefined12Error Invalid Mode Selection13-15Undefined16Error Access Restricted17-31Undefined32Error Busy33-127Undefined6.8Command 7 Read Loop ConfigurationRead polling address and the loop current mode.Request Data BytesByte Format DescriptionNoneResponse Data BytesByte Format Description0Unsigned-8Polling Address of Device (refer to the Data Link LayerSpecification)1Enum Loop Current Mode (refer to Common Table 16, LoopCurrent Modes)Command-Specific Response CodesCode Class Description0Success No Command-Specific Errors1-15Undefined16Error Access Restricted17-127Undefined6.9Command 8 Read Dynamic Variable ClassificationsReads the Classification associated with the Dynamic Variables. The Classification determines the Unit Code Expansion Table that must be used by a Host.Request Data BytesByte Format DescriptionNoneResponse Data BytesByte Format Description0Enum Primary Variable Classification (see Common Table 21,Device Variable Classification Codes)1Enum Secondary Variable Classification (see Common Table 21,Device Variable Classification Codes)2Enum Tertiary Variable Classification (see Common Table 21,Device Variable Classification Codes)3Enum Quaternary Variable Classification (see Common Table 21,Device Variable Classification Codes)Note:Dynamic Variables not supporting a Device Variable Classification must return 250 ("Not Used").Command-Specific Response CodesCode Class Description0Success No Command-Specific Errors1-15Undefined16Error Access Restricted17-127Undefined6.10Command 9 Read Device Variables with StatusThis command allows a Master to request the value and status of up to four Device or Dynamic Variables. In other words, a Master may request only 1, 2, 3 or 4 Device Variables. The Field Device must answer these Master requests without returning Response Code 5, Too Few Data Bytes Received. If the Field Device receives 1, 2 or 3 Request Data Bytes, it must return only the corresponding number of Device Variables (see Table 2).Table mand 9 Response Based on Number of Device VariablesRequestedNo. of Device Variables Requested No. of Request DatabytesNo. of Response DataBytes119221733254433If the Field Device does not expose its Device Variables, then the Field Device must return: PV when Device Variable zero is requested; SV for Device Variable one; TV for Device Variable two; and QV for Device Variable three. Other command requirements include:1.When a Dynamic or Device Variable requested is not supported in the Field Device, then thecorresponding Value must be set to "0x7F, 0xA0, 0x00, 0x00"; the Status must be set to 0x30,(i.e., Status = "Bad" and Limit = "Constant"); the Units Code. must be set to "250" NotUsed; and the Device Variable Classification set to "0", Not Yet Classified.2.When the Device Variable Classification is not supported for a requested Dynamic or DeviceVariable, then "0", Not Yet Classified, must be returned in that field of the response .3.This command is capable of Burst Mode Operation and is configured with Command 107,Write Burst Mode Device Variables.Request Data BytesByte Format Description0Unsigned-8Slot 0: Device Variable Code (see Device Variable Code Tablein appropriate device-specific document)1Unsigned-8Slot 1: Device Variable Code2Unsigned-8Slot 2: Device Variable Code3Unsigned-8Slot 3: Device Variable CodeResponse Data BytesByte Format Description0Bits Extended Field Device Status (refer to Common Table 17,Extended Field Device Status)1Unsigned-8Slot 0: Device Variable Code (see Device Variable Code Tablein appropriate device-specific document)2Enum Slot 0: Device Variable Classification3Enum Slot 0: Units Code (refer to Common Tables Specification)4 - 7Float Slot 0: Device Variable Value8Bits Slot 0: Device Variable Status (see the appropriate DeviceFamily Status Common Table)9Unsigned-8Slot 1: Device Variable Code10Enum Slot 1: Device Variable Classification11Enum Slot 1: Units Code (refer to Common Tables Specification)12 - 15Float Slot 1: Device Variable Value16Bits Slot 1: Device Variable Status17Unsigned-8Slot 2: Device Variable Code18Enum Slot 2: Device Variable Classification19Enum Slot 2: Units Code (refer to Common Tables Specification)20 - 23Float Slot 2: Device Variable Value24Bits Slot 2: Device Variable Status。
using System;using System.Collections.Generic;using System.Data;using System.Data.SqlClient;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;//***************HART协议说明***********************************//////HART命令查询帧格式:0xFF+0xFF+定界符+地址+数据字节数+数据+校验和//1、前导符:2-20字节,用于与接收器之间的同步//首次开始通信或数据帧重发时,使用20字节前导码,前导码都是0xFF。
//2、定界符:1字节,短帧:01,02,06对应成组、主从、从主三种模式,长帧时将短帧最高位置1即可//3、长帧和短帧区别在于地址的字节数不同,短帧地址为1字节,用于初始化时命令0查询设备标志、ID等信息//长帧地址:5字节(40位),建立在设备唯一标识符的基础上//唯一标识符分为三个部分://第一字节最高位,1表示基本主设备,0表示副主设备//第一字节第六位(次高位),1表示处于成组模式,0表示没有成组模式//长地址的其它部分是设备的唯一标识符,共38位,均为0表示广播地址//二.二短帧地址:1字节//最高位1表示主设备,0表示副主设备//第6位1表示处于成组模式,0表示没有处于成组模式//第4、5位必须置0//最低四位表示巡检地址,对应设备巡检地址0-15//4、命令字节:1字节,表明该帧所封装的HART命令,命令字节值在从设备响应中原值返回//5、字节奇数:1字节,表明此字节与最后帧校验字节之间的数据字节个数,用于识别帧的结束,范围0-27//6、数据域:由整数字节的用户数据组成,长度为0-25字节//在主-从帧中,数据域存放用户对设备的请求数据//在从-主帧中,数据用于存放设备对用户的响应数据//7、校验字节:1字节,对不包括前导符和该字节的帧中所有字节进行水平校验(异或)的结果//垂直校验时通信过程中硬件自动对每个字节所有位进行奇偶校验后产生的结果//水平校验时所有字节依次按位进行异或运算后的结果//8、响应码:只在从帧中出现//响应码第一字节指明通信状态,第二字节表示现场设备工作状态//该帧数据只有在响应码第一字节最高位为0时有效,1表示通信错误namespace Hart{public partial class from1 : Form{//HART对应串口初始化Private SerialPort serial_hart = new SerialPort();Private void portInit(){serial_hart.PortName = hart[0]["port"].ToString();serial_hart.BaudRate = Convert.ToInt32(hart[0]["baudrate"]);serial_hart.ReceivedBytesThreshold = 1;serial_hart.Parity = Parity.Odd;try{serial_hart.Open();int n = serial_hart.BytesToRead; //串口缓存区待读取数据个数byte[] buffirstclear = new byte[n];serial_hart.Read(buffirstclear, 0, n);//将串口缓存区之前的数据清理掉,防止过量非预期数据进入解析环节buffirstclear = new byte[1]; //释放变量空间}catch (Exception ex){if (ex.ToString() != ex1){ex1 = ex.ToString();MessageBox.Show(ex.Message);}}}#region 设备信息private int manufacID = 18; //制造商IDprivate int devType = 8; //制造商设备类型private int sfVersion = 1; //软件版本号private int hwVersion = 0; //硬件版本号private int[] devID = new int[3]; //设备IDprivate int cmdVersion = 5; //通用命令文档版本号private int devIDResult = 0; //设备ID计算结果#endregion#region 主变量(PV)private int PVUnitCd = 0; //主变量代码private float PVValue = 0; //主变量private float PVCurrent = 0; //主变量电流private float PVPercentRange = 0; //主变量量程百分比private int PVSensNum = 0; //主变量传感器编号private int PVSensUnitCd = 0; //传感器极限、最小精度单位代码private float PVUpSensLmt = 0; //传感器上限private float PVLowSensLmt = 0; //传感器下限private float PVMiniSpan = 0; //主变量最小精度private int PVAlarmSelCd = 0; //主变量报警选择代码private int PVTransFuncCd = 0; //主变量传递功能代码private int PVRangeUnitCd = 0; //主变量上下量程单位代码private float PVUpRangeValue = 0; //主变量上限值private float PVLowRangValue = 0;//主变量下限值private float PVDampValue = 0; //主变量阻尼值,单位秒private int WriteProtectCd = 251; //写保护代码private int PLDCd = 18; //商标发行商代码,18-ABB公司#endregion#region 第二...第四变量private int SecVUnitCd = 0; //第二变量代码private float SecVValue = 0; //第二变量值private int ThirdVUnitCd = 0; //第三变量代码private float ThirdVValue = 0; //第三变量值private int ForthVUnitCd = 0; //第四变量代码private float ForthVValue = 0; //第四变量值#endregion#region 标签、描述符、日期(日月年)private string hartTag = ""; //标签private string hartDspt = ""; //描述private string hartDate = ""; //日期#endregion#region 通用命令帧头private byte[] cmdHead = new byte[14]; //帧头包含导引符、定界符、地址private int cmdHeadInitFlag = 0; //帧头初始化标志#endregion#region 常量表、动态变量表public DataTable hartConstant = new DataTable();public DataTable hartDynamic = new DataTable();#endregionprivate int IDHartConstant = 0; //常量表IDprivate int IDHartDynamic = 0; //动态变量表IDprivate string errorstr = ""; //错误信息字符串private string hartMsg = ""; //读设备消息返回结果public string[] HartParaShow = new string[6];private int FinalAssembleNum = 0; //最终装配号private int[] hartGetCmdOk = new int[9]; //9个通用查询命令,查询成功后对应单元数置1#region 常量表初始化private void HartConstantInit()hartConstant.Columns.Add("ID", typeof(int));hartConstant.Columns.Add("Time", typeof(string));hartConstant.Columns.Add("制造商ID", typeof(int));hartConstant.Columns.Add("制造商设备类型", typeof(int));hartConstant.Columns.Add("通用命令文档版本号", typeof(int));hartConstant.Columns.Add("设备软件版本号", typeof(int));hartConstant.Columns.Add("设备硬件版本号", typeof(int));hartConstant.Columns.Add("设备ID号", typeof(int));hartConstant.Columns.Add("设备消息", typeof(string));hartConstant.Columns.Add("标签Tag", typeof(string));hartConstant.Columns.Add("描述符", typeof(string));hartConstant.Columns.Add("日期", typeof(string));hartConstant.Columns.Add("传感器序列号", typeof(int));hartConstant.Columns.Add("传感器上下限单位代码", typeof(int));hartConstant.Columns.Add("传感器上限", typeof(float));hartConstant.Columns.Add("传感器下限", typeof(float));hartConstant.Columns.Add("主变量最小精度", typeof(float));hartConstant.Columns.Add("报警选择代码", typeof(int));hartConstant.Columns.Add("传递功能代码", typeof(int));hartConstant.Columns.Add("上下量程值代码", typeof(int));hartConstant.Columns.Add("主变量上限值", typeof(float));hartConstant.Columns.Add("主变量下限值", typeof(float));hartConstant.Columns.Add("主变量阻尼值", typeof(float));hartConstant.Columns.Add("写保护代码", typeof(int));hartConstant.Columns.Add("最终装配号", typeof(int));}#endregion#region 动态变量表初始化private void HartDynamicInit(){hartDynamic.Columns.Add("ID", typeof(int));hartDynamic.Columns.Add("Time", typeof(string));hartDynamic.Columns.Add("设备ID号", typeof(int));hartDynamic.Columns.Add("主变量单位代码", typeof(int));hartDynamic.Columns.Add("主变量值", typeof(float));hartDynamic.Columns.Add("主变量电流", typeof(float));hartDynamic.Columns.Add("主变量量程百分比", typeof(float));hartDynamic.Columns.Add("第二变量单位代码", typeof(int));hartDynamic.Columns.Add("第二变量值", typeof(int));hartDynamic.Columns.Add("第三变量单位代码", typeof(int));hartDynamic.Columns.Add("第三变量值", typeof(int));hartDynamic.Columns.Add("第四变量单位代码", typeof(int));hartDynamic.Columns.Add("第四变量值", typeof(int));#endregion#region 发送命令0(读标识码)查询请求private void hartSendCmd0() //发送命令0(读标识码)查询请求{if (hartopenflag == 1){byte[] cmd = new byte[13];for (int i = 0; i < 8; i++){cmd[i] = 0xff; //第一次通信前导符为20个0xFF}cmd[8] = 0x02; //短帧,主从模式cmd[9] = 0x80; //主设备cmd[10] = 0x00; //命令0cmd[11] = 0x00; //数据长度0cmd[12] = Convert.ToByte( cmd[8] ^ cmd[9] ^ cmd[10] ^ cmd[11]); //水平校验serial_hart.Write(cmd, 0, 13);}}#endregion#region 发送无请求数据的长帧通用方法private void hartLongFrameCmdsend(byte cmdn) //发送无请求数据的长帧通用方法{byte[] cmd = new byte[17];if (cmdHeadInitFlag == 1) //获取到设备信息后{for (int i = 0; i < 14; i++){cmd[i] = cmdHead[i]; //帧头赋值}cmd[14] = 1; //命令1cmd[15] = cmdn; //无请求数据cmd[16] = cmd[8];for (int i = 9; i < 16; i++){cmd[16] = Convert.ToByte(cmd[16] ^ cmd[i]); //校验和}serial_hart.Write(cmd, 0, 17); //发送请求}}#endregion#region 无请求数据的长地址查询private void hartSendCmd1() //发送通用命令1(读主变量)查询请求{hartLongFrameCmdsend(1);}private void hartSendCmd2() //发送通用命令2(读主变量电流值和百分比)查询请求{hartLongFrameCmdsend(2);}private void hartSendCmd3() //发送通用命令3(读动态变量和主变量电流)查询请求{hartLongFrameCmdsend(3);}private void hartSendCmd12() //发送通用命令12(读消息)查询请求{hartLongFrameCmdsend(12);}private void hartSendCmd13() //发送通用命令13(读标签Tag)查询请求{hartLongFrameCmdsend(13);}private void hartSendCmd14() //发送通用命令14(读主变量传感器信息)查询请求{hartLongFrameCmdsend(14);}private void hartSendCmd15() //发送通用命令15(读主变量输出信息)查询请求{hartLongFrameCmdsend(15);}private void hartSendCmd16() //发送通用命令16(读最终装配号)查询请求{hartLongFrameCmdsend(16);}private void hartSendCmd48() //发送常用命令48(读附加器件状态)查询请求{hartLongFrameCmdsend(48);}#endregion#region 命令0返回值解析(标识码)private void hartGetCmd0() //获取命令0设备返回的数据并解析{//预期接收到设备返回的数据为://FF FF FF FF FF FF FF FF 06 80 00 0E 00 00 FE 12 08 08 05 00 01 00或01 00 00 设备ID高字节设备ID低字节int n = serial_hart.BytesToRead;int begin = 0;byte[] buf;if (n >24){buf = new byte[n];serial_hart.Read(buf, 0, n);for (int i = 0; i < 9; i++){if ((buf[i] == 0x06) & (buf[i + 1] == 0x80) & (buf[i + 2] == 0x0) &(buf[i + 3] == 12)){begin = i;if ((buf[i + 4] == 0) & (buf[i + 5] == 0)){manufacID = buf[i + 7];devType = buf[i + 8];cmdVersion = buf[i + 10];sfVersion = buf[i + 12];hwVersion = buf[i + 13];devID[0] = buf[i + 15];devID[1] = buf[i + 16];devID[2] = buf[i + 17];devIDResult = devID[1] * 256 + devID[2];hartGetCmdOk[0] = 1; //返回值接收成功标志置1cmdHeadInit(); //初始化命令帧头}else{errorstr = "数据长度有误!";pictureBox_Normal.Image = Properties.Resources.异常;label_Right.Text = "异常";label_Hint.Text = "Hart通用命令0" + errorstr;hartSendCmd0(); //未能获取到设备信息则重新发送请求}}}}}#endregion#region 数据解析查找帧头相关变量private int headbegin = 0; //分界符位置private int headFindFlag = 0; //找到分解符标志#endregion#region 判断返回值是否正确,并找到帧头(分界符位置)//判断帧头(定界符)位置private void findFrameHead(byte[] buf1, byte cmdn,byte datanum){for (int i = 0; i < 10; i++){if ((buf1[i] == 0x86) & (buf1[i + 1] == cmdHead[9]) &(buf1[i + 2] == cmdHead[10]) & (buf1[i + 3] == cmdHead[11]) &(buf1[i + 4] == cmdHead[12]) & (buf1[i + 5] == cmdHead[13]) &(buf1[i + 6] == cmdn) & (buf1[i + 7] == datanum)){if ((buf1[i + 8] == 0) & (buf1[i + 9] == 0)){headbegin = i;headFindFlag = 1;}if ((buf1[i + 8] == 0) & (buf1[i + 9] == 5)){errorstr = "命令" + cmdn.ToString() + "返回结果异常,字节数不对!!";pictureBox_Normal.Image = Properties.Resources.异常;label_Right.Text = "异常";label_Hint.Text = errorstr;}}}}#endregion#region 查询命令通用帧头设置private void cmdHeadInit() //初始化命令帧头,只有在获取到设备信息后才会有此标志为1{for (int i = 0; i < 8; i++){cmdHead[i] = 0xff;}cmdHead[8] = 0x82;cmdHead[9] = Convert.ToByte( manufacID);cmdHead[9] |=0x80;cmdHead[10] = Convert.ToByte(devType);for (int i = 0; i < 3; i++){cmdHead[i + 11] = Convert.ToByte(devID[i]);}cmdHeadInitFlag = 1;}#endregion#region 命令1返回值解析(主变量PV)//命令1返回值解析//预期返回值为:FF FF FF FF FF FF FF FF 86 #add1 #add2 #add3 #add4 #add5 0x01 0x05 00 00 #0 #1...#4// ///////*********前导符*****///定界符//**************地址********//命令//数据长度//状态//主变量单位代码//主变量private void hartGetCmd1(){int n = serial_hart.BytesToRead;byte[] buf;byte cmdn = 1;byte datanum = 5;if (n > 18){buf = new byte[n];serial_hart.Read(buf, 0, n);findFrameHead(buf, cmdn, datanum);if (headFindFlag == 1){PVUnitCd = buf[headbegin + 10];PVValue = BitConverter.ToSingle(buf, headbegin + 11);hartGetCmdOk[1] = 1;headFindFlag = 0;headbegin = 0;}else{hartSendCmd1();}}}#endregion#region 命令2返回值解析(主变量电流值和百分比)//命令2返回值解析//预期返回值为:FF FF FF FF FF FF FF FF 86 #add1 #add2 #add3 #add4 #add5 0x02 0x18 00 00 #0..#3 #4...#7// ///////*******8个前导符*****///定界符//*********5字节地址********//命令//数据长度//状态//主变量电流//主变量量程百分比private void hartGetCmd2(){int n = serial_hart.BytesToRead;byte[] buf;byte cmdn = 2;byte datanum = 8;if (n > 18){buf = new byte[n];serial_hart.Read(buf, 0, n);findFrameHead(buf, cmdn, datanum);if (headFindFlag == 1){PVCurrent = BitConverter.ToSingle(buf, headbegin + 10);PVPercentRange = BitConverter.ToSingle(buf, headbegin + 14);hartGetCmdOk[2] = 1;headFindFlag = 0;headbegin = 0;}else{hartSendCmd2();}}}#endregion#region 命令3返回值解析(主变量电流和动态变量)//命令3返回值解析//预期返回值为:FF FF FF FF FF FF FF FF 86 #add1 #add2 #add3 #add4 #add5 0x03 0x18 00 00 #0..#3 #4// ///////*******8个前导符*****///定界符//*********5字节地址********//命令//数据长度//状态//主变量电流//主变量单位代码// #5...#8 #9 #10...#13 #14 #15...#18 #19 #20...#23//主变量值*第二变量代码*第二变量值*第三变量代码*第三变量值*第四变量代码*第四变量值private void hartGetCmd3(){int n = serial_hart.BytesToRead;byte[] buf;byte cmdn = 3;byte datanum = 24;if (n >34 ){buf = new byte[n];serial_hart.Read(buf, 0, n);findFrameHead(buf, cmdn, datanum);if (headFindFlag == 1){PVCurrent = BitConverter.ToSingle(buf, headbegin + 10);PVUnitCd = buf[headbegin + 14];PVValue = BitConverter.ToSingle(buf, headbegin + 15);SecVUnitCd = buf[headbegin + 19];SecVValue = BitConverter.ToSingle(buf, headbegin + 20);ThirdVUnitCd = buf[headbegin + 24];ThirdVValue = BitConverter.ToSingle(buf, headbegin + 25);ForthVUnitCd = buf[headbegin + 29];ForthVValue = BitConverter.ToSingle(buf, headbegin + 30);hartGetCmdOk[3] = 1;headFindFlag = 0;headbegin = 0;}else{hartSendCmd3();}}}#endregion#region 命令12返回值解析(设备消息)//该命令用于读取设备消息// //预期返回值为:FF FF FF FF FF FF FF FF 86 #add1 #add2 #add3 #add4 #add5 0x0C 0x18 00 00 #0..#23// ////*******8个前导符*****///定界符//*********5字节地址********//命令//数据长度//状态//设备消息(ASCII)private void hartGetCmd12(){int n = serial_hart.BytesToRead;byte[] buf;byte cmdn = 12;byte datanum ;if (n > 18){buf = new byte[n];serial_hart.Read(buf, 0, n);datanum = Convert.ToByte(n-18); //是24还是实际字符串长度不确定findFrameHead(buf, cmdn, datanum);if (headFindFlag == 1){StringBuilder strb = new StringBuilder();for (int i = 0; i < datanum; i++){strb.Append((char)buf[headbegin + 10 + i]);}hartMsg = strb.ToString();hartGetCmdOk[4] = 1;headFindFlag = 0;headbegin = 0;}else{hartSendCmd12();}}}#endregion#region 命令13返回值解析(标签描述)//命令3返回值解析//预期返回值为:FF FF FF FF FF FF FF FF 86 #add1 #add2 #add3 #add4 #add5 0x0D 0x18 00 00 #0..#5 #6...#17// ///////*******8个前导符*****///定界符//*********5字节地址********//命令//数据长度//状态//设备的Tag//描述符// #18...#20// 日期:日月年private void hartGetCmd13(){int n = serial_hart.BytesToRead;byte[] buf;byte cmdn = 13;byte datanum=21;if (n >31){buf = new byte[n];serial_hart.Read(buf, 0, n);findFrameHead(buf, cmdn, datanum);if (headFindFlag == 1){StringBuilder strb = new StringBuilder();for (int i = 0; i < 6; i++){strb.Append((char)buf[headbegin + 10 + i]);}hartTag = strb.ToString();strb.Clear();for (int i = 6; i < 18; i++){strb.Append((char)buf[headbegin + 10 + i]);}hartDspt = strb.ToString();hartDate = buf[headbegin + 20].ToString() + "年" +buf[headbegin + 19].ToString() + "月" +buf[headbegin + 18].ToString() + "日";hartGetCmdOk[5] = 1;headFindFlag = 0;headbegin = 0;}else{hartSendCmd13();}}}#endregion#region 命令14返回值解析(主变量传感器信息)//命令14返回值解析//预期返回值为:FF FF FF FF FF FF FF FF 86 #add1 #add2 #add3 #add4 #add5 0x0E 0x10 00 00 #0..#2 #3// ///////*******8个前导符*****///定界符//*********5字节地址********//命令//数据长度//状态//传感器序列号//单位代码// #4...#7 #8...#11 #12...#15// 传感器上限*传感器下限*主变量最小精度private void hartGetCmd14(){int n = serial_hart.BytesToRead;byte[] buf;byte cmdn = 14;byte datanum = 16;if (n > 26){buf = new byte[n];serial_hart.Read(buf, 0, n);findFrameHead(buf, cmdn, datanum);if (headFindFlag == 1){PVSensNum = (buf[headbegin + 10] << 16) & 0xff0000 + (buf[headbegin + 11] << 8) & 0xff00 + buf[headbegin + 12];PVSensUnitCd = buf[headbegin + 13];PVUpSensLmt = BitConverter.ToSingle(buf, headbegin + 14);PVLowSensLmt = BitConverter.ToSingle(buf, headbegin + 18);PVMiniSpan = BitConverter.ToSingle(buf, headbegin + 22);hartGetCmdOk[6] = 1;headFindFlag = 0;headbegin = 0;}else{hartSendCmd14();}}}#endregion#region 命令15返回值解析(主变量输出信息)//命令15返回值解析//预期返回值为:FF FF FF FF FF FF FF FF 86 #add1 #add2 #add3 #add4 #add5 0x0F 0x10 00 00 #0 #1// ///////*******8个前导符*****///定界符//*********5字节地址********//命令//数据长度//状态//报警选择代码//传递功能代码// #2 #3...#6 #7...#10 #11..#14 #15 #16// 上下量程单位代码*主变量上限*主变量下限*阻尼值**写保护代码*发行商代码/*private int PVAlarmSelCd = 0; //主变量报警选择代码private int PVTransFuncCd = 0; //主变量传递功能代码private int PVRangeUnitCd = 0; //主变量上下量程单位代码private float PVUpRangeValue = 0; //主变量上限值private float PVLowRangValue = 0;//主变量下限值private float PVDampValue = 0; //主变量阻尼值,单位秒private int WriteProtectCd = 251; //写保护代码private int PLDCd = 18; //商标发行商代码,18-ABB公司*/private void hartGetCmd15(){int n = serial_hart.BytesToRead;byte[] buf;byte cmdn = 15;byte datanum = 17;if (n > 27){buf = new byte[n];serial_hart.Read(buf, 0, n);findFrameHead(buf, cmdn, datanum);if (headFindFlag == 1){PVAlarmSelCd = buf[headbegin + 10];PVTransFuncCd = buf[headbegin + 11];PVRangeUnitCd = buf[headbegin + 12];PVUpRangeValue = BitConverter.ToSingle(buf, headbegin + 13);PVLowRangValue = BitConverter.ToSingle(buf, headbegin + 17);PVDampValue = BitConverter.ToSingle(buf, headbegin + 21);WriteProtectCd = buf[headbegin + 25];PLDCd = buf[headbegin + 26];hartGetCmdOk[7] = 1;headFindFlag = 0;headbegin = 0;}else{hartSendCmd15();}}}#endregion#region 命令16返回值解析(最终装配号)//命令15返回值解析//预期返回值为:FF FF FF FF FF FF FF FF 86 #add1 #add2 #add3 #add4 #add5 0x0F 0x10 00 00 #0 #1// ///////*******8个前导符*****///定界符//*********5字节地址********//命令//数据长度//状态//报警选择代码//传递功能代码// #2 #3...#6 #7...#10 #11..#14 #15 #16// 上下量程单位代码*主变量上限*主变量下限*阻尼值**写保护代码*发行商代码private void hartGetCmd16(){int n = serial_hart.BytesToRead;byte[] buf;byte cmdn = 16;byte datanum = 3;if (n > 27){buf = new byte[n];serial_hart.Read(buf, 0, n);findFrameHead(buf, cmdn, datanum);if (headFindFlag == 1){FinalAssembleNum = buf[headbegin + 10] * 65536 + buf[headbegin + 11]* 256 + buf[headbegin + 12];hartGetCmdOk[8] = 1;headFindFlag = 0;headbegin = 0;}else{hartSendCmd16();}}}#endregionprivate void hartSaveConstantTable() //常量存入常量表{DataRow hartc = hartConstant.NewRow();hartc["ID"] = IDHartConstant;hartc["Time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");hartc["制造商ID"] = manufacID;hartc["制造商设备类型"] = devType;hartc["通用命令文档版本号"] = cmdVersion;hartc["设备软件版本号"] = sfVersion;hartc["设备硬件版本号"] = hwVersion;hartc["设备ID号"] = devID;hartc["设备消息"] = hartMsg;hartc["标签Tag"] = hartTag;hartc["描述符"] = hartDspt;hartc["日期"] = hartDate;hartc["传感器序列号"] = PVSensNum;hartc["传感器上下限单位代码"] = PVSensUnitCd;hartc["传感器上限"] = PVUpSensLmt;hartc["传感器下限"] = PVLowSensLmt;hartc["主变量最小精度"] = PVMiniSpan;hartc["报警选择代码"] = PVAlarmSelCd;hartc["传递功能代码"] = PVTransFuncCd;hartc["上下量程值代码"] = PVRangeUnitCd;hartc["主变量上限值"] = PVUpRangeValue;hartc["主变量下限值"] = PVLowRangValue;hartc["主变量阻尼值"] = PVDampValue;hartc["写保护代码"] = WriteProtectCd;hartc["最终装配号"] = PLDCd;hartConstant.Rows.Add(hartc);}private void strHartCSet(StringBuilder str) //字符串赋值{str.Append("ID,");str.Append("Time,");str.Append("制造商ID,");str.Append("制造商设备类型,");str.Append("通用命令文档版本号,");str.Append("设备软件版本号,");str.Append("设备硬件版本号,");str.Append("设备ID号,");str.Append("设备消息,");str.Append("标签Tag,");str.Append("描述符,");str.Append("日期,");str.Append("传感器序列号,");str.Append("传感器上下限单位代码,");str.Append("传感器上限,");str.Append("传感器下限,");str.Append("主变量最小精度,");str.Append("报警选择代码,");str.Append("传递功能代码,");str.Append("上下量程值代码,");str.Append("主变量上限值,");str.Append("主变量下限值,");str.Append("主变量阻尼值,");str.Append("写保护代码,");str.Append("最终装配号");}public int[] hartViewItemSct = new int[6];/* private string[] hartConstItem = { "ID", "Time", "制造商ID", "制造商设备类型", "通用命令文档版本号","设备软件版本号", "", "", "", "","", "", "", "", "","", "", "", "", "","", "", "", "", "",};*/private void strHartDSet(StringBuilder str){str.Append("ID,");str.Append("Time,");str.Append("设备ID号,");str.Append("主变量单位代码,");str.Append("主变量值,");str.Append("主变量电流,");str.Append("主变量量程百分比,");str.Append("第二变量单位代码,");str.Append("第二变量值,");str.Append("第三变量单位代码,");str.Append("第三变量值,");str.Append("第四变量单位代码,");str.Append("第四变量值");}private void hartSaveConstantDb() //常量存入数据库{if (hartConstant.Rows.Count > 0){StringBuilder strHartC = new StringBuilder();strHartCSet(strHartC); //字符串赋值string saveStr = strHartC.ToString();int m = hartConstant.Rows.Count - 1;SqlCommand com = new SqlCommand(String.Format("insert into HartConstant('{0}')Values({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})", saveStr, hartConstant.Rows[m]["ID"], hartConstant.Rows[m]["Time"], hartConstant.Rows[m]["制造商ID"],hartConstant.Rows[m]["制造商设备类型"], hartConstant.Rows[m]["通用命令文档版本号"],hartConstant.Rows[m]["设备软件版本号"], hartConstant.Rows[m]["设备硬件版本号"], hartConstant.Rows[m]["设备ID号"],hartConstant.Rows[m]["设备消息"], hartConstant.Rows[m]["标签Tag"],hartConstant.Rows[m]["描述符"], hartConstant.Rows[m]["日期"],hartConstant.Rows[m]["传感器序列号"], hartConstant.Rows[m]["传感器上下限单位代码"],hartConstant.Rows[m]["传感器上限"], hartConstant.Rows[m]["传感器下限"],hartConstant.Rows[m]["主变量最小精度"], hartConstant.Rows[m]["报警选择代码"],hartConstant.Rows[m]["传递功能代码"], hartConstant.Rows[m]["上下量程值代码"],hartConstant.Rows[m]["主变量上限值"], hartConstant.Rows[m]["主变量下限值"],hartConstant.Rows[m]["主变量阻尼值"], hartConstant.Rows[m]["写保护代码"],hartConstant.Rows[m]["最终装配号"]), dbcon);try{com.ExecuteNonQuery();}catch (Exception ex){MessageBox.Show(ex.Message);}}}private void hartSaveDynamicTable() //动态变量存入动态变量表{DataRow hartd = hartDynamic.NewRow();hartd["ID"] = IDHartDynamic;hartd["Time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");hartd["设备ID号"] = devID;hartd["主变量单位代码"] = PVUnitCd;hartd["主变量值"] = PVValue;hartd["主变量电流"] = PVCurrent;hartd["主变量量程百分比"] = PVPercentRange;hartd["第二变量单位代码"] = SecVUnitCd;hartd["第二变量值"] = SecVValue;hartd["第三变量单位代码"] = ThirdVUnitCd;hartd["第三变量值"] = ThirdVValue;hartd["第四变量单位代码"] = ForthVUnitCd;hartd["第四变量值"] = ForthVValue;hartDynamic.Rows.Add(hartd);}private void hartSaveDynamicDb() //动态变量存入数据看{if (hartDynamic.Rows.Count > 0){StringBuilder strHartD = new StringBuilder();strHartDSet(strHartD); //字符串赋值string saveStr = strHartD.ToString();int m = hartDynamic.Rows.Count - 1;SqlCommand com = new SqlCommand(String.Format("insert into HartDynamic('{0}')Values ({1},'{2}',{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13})", saveStr, hartDynamic.Rows[m]["ID"], hartDynamic.Rows[m]["Time"], hartDynamic.Rows[m]["设备ID号"],hartDynamic.Rows[m]["主变单位代码"], hartDynamic.Rows[m]["主变量值"],hartDynamic.Rows[m]["主变量电流"], hartDynamic.Rows[m]["主变量量程百分比"],hartDynamic.Rows[m]["第二变量单位代码"], hartDynamic.Rows[m]["第二变量值"],hartDynamic.Rows[m]["第三变量单位代码"], hartDynamic.Rows[m]["第三变量值"],hartDynamic.Rows[m]["第四变量单位代码"], hartDynamic.Rows[m]["第四变量值"]), dbcon);try{com.ExecuteNonQuery();}catch (Exception ex){MessageBox.Show(ex.Message);}}}#region 存储常量(数据库、数据表)private void hartSaveConstant(){if (dbcon_flag == 1){if (dbconOpenNow == 0){dbconOpen();}string sqlquery = "select top 1 ID from HartConstant order by ID desc";try{SqlDataAdapter sda = new SqlDataAdapter(sqlquery, dbcon);DataSet ds = new DataSet();sda.Fill(ds);//把查询结果填充在ds里if (ds.Tables[0].Rows.Count == 1){IDHartConstant = Convert.ToInt32(ds.Tables[0].Rows[0][0]) + 1;}elseIDHartConstant = 0;}catch (Exception ex){MessageBox.Show(ex.Message);}hartSaveConstantTable();hartSaveConstantDb();if (dbconOpenNow == 1){dbconClose();}}else{if (hartConstant.Rows.Count > 0){IDHartConstant = Convert.ToInt32(hartConstant.Rows[hartConstant.Rows.Count - 1]["ID"]) + 1;}else{IDHartConstant = 0;}hartSaveConstantTable();}}#endregion#region 存储动态变量(数据库、数据表)private void hartSaveDynamic(){if (dbcon_flag == 1){if (dbconOpenNow == 0){dbconOpen();}string sqlquery = "select top 1 ID from HartDynamic order by ID desc";try{SqlDataAdapter sda = new SqlDataAdapter(sqlquery, dbcon);DataSet ds = new DataSet();sda.Fill(ds);//把查询结果填充在ds里if (ds.Tables[0].Rows.Count == 1){IDHartDynamic = Convert.ToInt32(ds.Tables[0].Rows[0][0]) + 1;}elseIDHartDynamic = 0;}catch (Exception ex){MessageBox.Show(ex.Message);}hartSaveDynamicTable();hartSaveDynamicDb();if (dbconOpenNow == 1){dbconClose();}}else{if (hartDynamic.Rows.Count > 0){IDHartDynamic = Convert.ToInt32(hartDynamic.Rows[hartDynamic.Rows.Count - 1]["ID"]) + 1;}else{IDHartDynamic = 0;}hartSaveDynamicTable();}}#endregionprivate int hartNum = 0; //HART收发计数器,偶数发查询命令,奇数解析设备返回数据private int hartCmdNum = 0; //控制HART发送解析具体命令private int hartInitFlag = 0; //Hart设备初始化标识private int hartWorkFlag = 0; //Hart设备工作标识private int hartSleepFlag = 0; //Hart设备暂停查询标识(两分钟查询一次变量)private int hartSleepNum = 0; //Hart设备休眠时间private int hartInitOkFlag = 0; //初始化完成标识,用于更新主界面常量相关的参数显示#region HART设备初始化,主要是查询设备标识及常量信息//HART初始化private void hartInit(){if ((hartNum % 2) == 0){#region 发送初始化需要的查询指令switch (hartCmdNum){case 0:hartSendCmd0();hartNum++;hartInitOkFlag = 0;break;case 12:。
hart命令举例-回复Hart命令是一种用于计算机系统中的命令行工具。
它可以用于执行各种系统管理任务,包括文件和目录操作、进程管理、网络设置等。
在本文中,我们将以“网络设置”作为主题,介绍一些Hart命令的使用方法。
Hart命令可以帮助我们轻松地配置和管理网络设置,包括IP地址、子网掩码、网关、DNS等。
以下是几个常用的Hart命令示例,用于展示如何使用这些命令来设置和管理网络。
1. 查看网络配置:首先,我们可以使用“hart ip show”命令来查看当前系统的网络配置。
打开命令行接口,并输入以下命令:hart ip show这个命令将显示当前系统的IP地址、子网掩码和网关信息。
通过查看这些信息,我们可以了解当前网络的配置情况。
2. 配置网络接口:如果我们希望配置网络接口,例如更改IP地址或子网掩码,可以使用“hart ip set”命令。
以下是一个示例:hart ip set eth0 address 192.168.0.100hart ip set eth0 netmask 255.255.255.0这个命令将更改eth0网络接口的IP地址为192.168.0.100,并将子网掩码设置为255.255.255.0。
我们可以根据需要修改这些值。
3. 配置默认网关:如果我们需要配置系统的默认网关,可以使用“hart route”命令。
以下是一个示例:hart route add default gateway 192.168.0.1这个命令将设置系统的默认网关为192.168.0.1。
通过设置默认网关,我们可以确保系统在与外部网络通信时能够正确路由数据。
4. 配置DNS服务器:如果我们需要配置DNS服务器,可以使用“hart dns set”命令。
以下是一个示例:hart dns set nameservers 8.8.8.8 8.8.4.4这个命令将设置系统的DNS服务器为8.8.8.8和8.8.4.4。
HART手持式操作通信器使用说明书目录一、使用说明 (2)二、连接 (2)三、主菜单 (3)四、在线调试状态 (4)1、过程变量 (4)2、附加信息 (5)3、量程修改 (5)4、环路测试 (6)5、线性化 (7)6、压力微调 (9)7、其它 (9)五、装箱清单项 (10)一、按键操作说明:光标移动键:光标在各项菜单中的上、下、左、右的移动。
字符选择键:只局限在修改数据过程中对数字信息的选取。
确认键:用于各菜单的选取和数字信息的选取。
修改键:用于对仪表的数据信息的修改。
背光键:用于背光的打开与关闭。
电源键:用于电源的打开与关闭。
退出键:用于各项菜单的退出。
功能键:用于扩展功能(待用)。
特定功能键:向上光标移动键:用于在监测“过程变量”中的退出。
二、连接所需仪器:一台智能变送器;一台HART手持式操作通信器(简称:手操器);一台12~45VDC电源;一个大于或等于250欧的负载电阻;一台精密毫安表或毫伏表;一台标准精密压力计(压力计精度至少比变送器高3倍)。
连接如下图所示:变送器线性化安装图注:为保证可靠通信,请将负载电阻串联在电源的正极。
三、主菜单按下面板中“电源开/关”按键,单点通讯将出现HART手操器主菜单。
如右轮询通讯图1所示:“单点通讯”在“零号地址码”可使用,若仪表的地址码不为“零号”,则应用“轮询通讯”方式通讯。
菜单中的“▋”为需要选择的图1 主菜单选项。
按“确认”按键进入在线调试状态(图2)四、在线调试状态在线调试状态是一个设置的窗口,主要包括七部分组成,如下图2中所示。
可根据用户的需要进行不同的读取与设置。
各个选项的具体操作说明在下面各章节中详细说明。
1、过程变量 如右图3所示。
本选项可以查看仪表的“PV ”(压力)、“I ”(电流)、“PER ”(百分数值)、“T ”(环境温度)、“LRV ”(零位)、“URV ”( 量程)、“LSL ”(最大测量范围低限)、“USL ”(最大测量范围高限)。
using System;using System.Collections.Generic;using System.Data;using System.Data.SqlClient;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;//***************HART协议说明***********************************//////HART命令查询帧格式:0xFF+0xFF+定界符+地址+数据字节数+数据+校验和//1、前导符:2-20字节,用于与接收器之间的同步//首次开始通信或数据帧重发时,使用20字节前导码,前导码都是0xFF。
//2、定界符:1字节,短帧:01,02,06对应成组、主从、从主三种模式,长帧时将短帧最高位置1即可//3、长帧和短帧区别在于地址的字节数不同,短帧地址为1字节,用于初始化时命令0查询设备标志、ID等信息//长帧地址:5字节(40位),建立在设备唯一标识符的基础上//唯一标识符分为三个部分://第一字节最高位,1表示基本主设备,0表示副主设备//第一字节第六位(次高位),1表示处于成组模式,0表示没有成组模式//长地址的其它部分是设备的唯一标识符,共38位,均为0表示广播地址//二.二短帧地址:1字节//最高位1表示主设备,0表示副主设备//第6位1表示处于成组模式,0表示没有处于成组模式//第4、5位必须置0//最低四位表示巡检地址,对应设备巡检地址0-15//4、命令字节:1字节,表明该帧所封装的HART命令,命令字节值在从设备响应中原值返回//5、字节奇数:1字节,表明此字节与最后帧校验字节之间的数据字节个数,用于识别帧的结束,范围0-27//6、数据域:由整数字节的用户数据组成,长度为0-25字节//在主-从帧中,数据域存放用户对设备的请求数据//在从-主帧中,数据用于存放设备对用户的响应数据//7、校验字节:1字节,对不包括前导符和该字节的帧中所有字节进行水平校验(异或)的结果//垂直校验时通信过程中硬件自动对每个字节所有位进行奇偶校验后产生的结果//水平校验时所有字节依次按位进行异或运算后的结果//8、响应码:只在从帧中出现//响应码第一字节指明通信状态,第二字节表示现场设备工作状态//该帧数据只有在响应码第一字节最高位为0时有效,1表示通信错误namespace Hart{public partial class from1 : Form{//HART对应串口初始化Private SerialPort serial_hart = new SerialPort();Private void portInit(){serial_hart.PortName = hart[0]["port"].ToString();serial_hart.BaudRate = Convert.ToInt32(hart[0]["baudrate"]);serial_hart.ReceivedBytesThreshold = 1;serial_hart.Parity = Parity.Odd;try{serial_hart.Open();int n = serial_hart.BytesToRead; //串口缓存区待读取数据个数byte[] buffirstclear = new byte[n];serial_hart.Read(buffirstclear, 0, n);//将串口缓存区之前的数据清理掉,防止过量非预期数据进入解析环节buffirstclear = new byte[1]; //释放变量空间}catch (Exception ex){if (ex.ToString() != ex1){ex1 = ex.ToString();MessageBox.Show(ex.Message);}}}#region 设备信息private int manufacID = 18; //制造商IDprivate int devType = 8; //制造商设备类型private int sfVersion = 1; //软件版本号private int hwVersion = 0; //硬件版本号private int[] devID = new int[3]; //设备IDprivate int cmdVersion = 5; //通用命令文档版本号private int devIDResult = 0; //设备ID计算结果#endregion#region 主变量(PV)private int PVUnitCd = 0; //主变量代码private float PVValue = 0; //主变量private float PVCurrent = 0; //主变量电流private float PVPercentRange = 0; //主变量量程百分比private int PVSensNum = 0; //主变量传感器编号private int PVSensUnitCd = 0; //传感器极限、最小精度单位代码private float PVUpSensLmt = 0; //传感器上限private float PVLowSensLmt = 0; //传感器下限private float PVMiniSpan = 0; //主变量最小精度private int PVAlarmSelCd = 0; //主变量报警选择代码private int PVTransFuncCd = 0; //主变量传递功能代码private int PVRangeUnitCd = 0; //主变量上下量程单位代码private float PVUpRangeValue = 0; //主变量上限值private float PVLowRangValue = 0;//主变量下限值private float PVDampValue = 0; //主变量阻尼值,单位秒private int WriteProtectCd = 251; //写保护代码private int PLDCd = 18; //商标发行商代码,18-ABB公司#endregion#region 第二...第四变量private int SecVUnitCd = 0; //第二变量代码private float SecVValue = 0; //第二变量值private int ThirdVUnitCd = 0; //第三变量代码private float ThirdVValue = 0; //第三变量值private int ForthVUnitCd = 0; //第四变量代码private float ForthVValue = 0; //第四变量值#endregion#region 标签、描述符、日期(日月年)private string hartTag = ""; //标签private string hartDspt = ""; //描述private string hartDate = ""; //日期#endregion#region 通用命令帧头private byte[] cmdHead = new byte[14]; //帧头包含导引符、定界符、地址private int cmdHeadInitFlag = 0; //帧头初始化标志#endregion#region 常量表、动态变量表public DataTable hartConstant = new DataTable();public DataTable hartDynamic = new DataTable();#endregionprivate int IDHartConstant = 0; //常量表IDprivate int IDHartDynamic = 0; //动态变量表IDprivate string errorstr = ""; //错误信息字符串private string hartMsg = ""; //读设备消息返回结果public string[] HartParaShow = new string[6];private int FinalAssembleNum = 0; //最终装配号private int[] hartGetCmdOk = new int[9]; //9个通用查询命令,查询成功后对应单元数置1#region 常量表初始化private void HartConstantInit()hartConstant.Columns.Add("ID", typeof(int));hartConstant.Columns.Add("Time", typeof(string));hartConstant.Columns.Add("制造商ID", typeof(int));hartConstant.Columns.Add("制造商设备类型", typeof(int));hartConstant.Columns.Add("通用命令文档版本号", typeof(int));hartConstant.Columns.Add("设备软件版本号", typeof(int));hartConstant.Columns.Add("设备硬件版本号", typeof(int));hartConstant.Columns.Add("设备ID号", typeof(int));hartConstant.Columns.Add("设备消息", typeof(string));hartConstant.Columns.Add("标签Tag", typeof(string));hartConstant.Columns.Add("描述符", typeof(string));hartConstant.Columns.Add("日期", typeof(string));hartConstant.Columns.Add("传感器序列号", typeof(int));hartConstant.Columns.Add("传感器上下限单位代码", typeof(int));hartConstant.Columns.Add("传感器上限", typeof(float));hartConstant.Columns.Add("传感器下限", typeof(float));hartConstant.Columns.Add("主变量最小精度", typeof(float));hartConstant.Columns.Add("报警选择代码", typeof(int));hartConstant.Columns.Add("传递功能代码", typeof(int));hartConstant.Columns.Add("上下量程值代码", typeof(int));hartConstant.Columns.Add("主变量上限值", typeof(float));hartConstant.Columns.Add("主变量下限值", typeof(float));hartConstant.Columns.Add("主变量阻尼值", typeof(float));hartConstant.Columns.Add("写保护代码", typeof(int));hartConstant.Columns.Add("最终装配号", typeof(int));}#endregion#region 动态变量表初始化private void HartDynamicInit(){hartDynamic.Columns.Add("ID", typeof(int));hartDynamic.Columns.Add("Time", typeof(string));hartDynamic.Columns.Add("设备ID号", typeof(int));hartDynamic.Columns.Add("主变量单位代码", typeof(int));hartDynamic.Columns.Add("主变量值", typeof(float));hartDynamic.Columns.Add("主变量电流", typeof(float));hartDynamic.Columns.Add("主变量量程百分比", typeof(float));hartDynamic.Columns.Add("第二变量单位代码", typeof(int));hartDynamic.Columns.Add("第二变量值", typeof(int));hartDynamic.Columns.Add("第三变量单位代码", typeof(int));hartDynamic.Columns.Add("第三变量值", typeof(int));hartDynamic.Columns.Add("第四变量单位代码", typeof(int));hartDynamic.Columns.Add("第四变量值", typeof(int));#endregion#region 发送命令0(读标识码)查询请求private void hartSendCmd0() //发送命令0(读标识码)查询请求{if (hartopenflag == 1){byte[] cmd = new byte[13];for (int i = 0; i < 8; i++){cmd[i] = 0xff; //第一次通信前导符为20个0xFF}cmd[8] = 0x02; //短帧,主从模式cmd[9] = 0x80; //主设备cmd[10] = 0x00; //命令0cmd[11] = 0x00; //数据长度0cmd[12] = Convert.ToByte( cmd[8] ^ cmd[9] ^ cmd[10] ^ cmd[11]); //水平校验serial_hart.Write(cmd, 0, 13);}}#endregion#region 发送无请求数据的长帧通用方法private void hartLongFrameCmdsend(byte cmdn) //发送无请求数据的长帧通用方法{byte[] cmd = new byte[17];if (cmdHeadInitFlag == 1) //获取到设备信息后{for (int i = 0; i < 14; i++){cmd[i] = cmdHead[i]; //帧头赋值}cmd[14] = 1; //命令1cmd[15] = cmdn; //无请求数据cmd[16] = cmd[8];for (int i = 9; i < 16; i++){cmd[16] = Convert.ToByte(cmd[16] ^ cmd[i]); //校验和}serial_hart.Write(cmd, 0, 17); //发送请求}}#endregion#region 无请求数据的长地址查询private void hartSendCmd1() //发送通用命令1(读主变量)查询请求{hartLongFrameCmdsend(1);}private void hartSendCmd2() //发送通用命令2(读主变量电流值和百分比)查询请求{hartLongFrameCmdsend(2);}private void hartSendCmd3() //发送通用命令3(读动态变量和主变量电流)查询请求{hartLongFrameCmdsend(3);}private void hartSendCmd12() //发送通用命令12(读消息)查询请求{hartLongFrameCmdsend(12);}private void hartSendCmd13() //发送通用命令13(读标签Tag)查询请求{hartLongFrameCmdsend(13);}private void hartSendCmd14() //发送通用命令14(读主变量传感器信息)查询请求{hartLongFrameCmdsend(14);}private void hartSendCmd15() //发送通用命令15(读主变量输出信息)查询请求{hartLongFrameCmdsend(15);}private void hartSendCmd16() //发送通用命令16(读最终装配号)查询请求{hartLongFrameCmdsend(16);}private void hartSendCmd48() //发送常用命令48(读附加器件状态)查询请求{hartLongFrameCmdsend(48);}#endregion#region 命令0返回值解析(标识码)private void hartGetCmd0() //获取命令0设备返回的数据并解析{//预期接收到设备返回的数据为://FF FF FF FF FF FF FF FF 06 80 00 0E 00 00 FE 12 08 08 05 00 01 00或01 00 00 设备ID高字节设备ID低字节int n = serial_hart.BytesToRead;int begin = 0;byte[] buf;if (n >24){buf = new byte[n];serial_hart.Read(buf, 0, n);for (int i = 0; i < 9; i++){if ((buf[i] == 0x06) & (buf[i + 1] == 0x80) & (buf[i + 2] == 0x0) &(buf[i + 3] == 12)){begin = i;if ((buf[i + 4] == 0) & (buf[i + 5] == 0)){manufacID = buf[i + 7];devType = buf[i + 8];cmdVersion = buf[i + 10];sfVersion = buf[i + 12];hwVersion = buf[i + 13];devID[0] = buf[i + 15];devID[1] = buf[i + 16];devID[2] = buf[i + 17];devIDResult = devID[1] * 256 + devID[2];hartGetCmdOk[0] = 1; //返回值接收成功标志置1cmdHeadInit(); //初始化命令帧头}else{errorstr = "数据长度有误!";pictureBox_Normal.Image = Properties.Resources.异常;label_Right.Text = "异常";label_Hint.Text = "Hart通用命令0" + errorstr;hartSendCmd0(); //未能获取到设备信息则重新发送请求}}}}}#endregion#region 数据解析查找帧头相关变量private int headbegin = 0; //分界符位置private int headFindFlag = 0; //找到分解符标志#endregion#region 判断返回值是否正确,并找到帧头(分界符位置)//判断帧头(定界符)位置private void findFrameHead(byte[] buf1, byte cmdn,byte datanum){for (int i = 0; i < 10; i++){if ((buf1[i] == 0x86) & (buf1[i + 1] == cmdHead[9]) &(buf1[i + 2] == cmdHead[10]) & (buf1[i + 3] == cmdHead[11]) &(buf1[i + 4] == cmdHead[12]) & (buf1[i + 5] == cmdHead[13]) &(buf1[i + 6] == cmdn) & (buf1[i + 7] == datanum)){if ((buf1[i + 8] == 0) & (buf1[i + 9] == 0)){headbegin = i;headFindFlag = 1;}if ((buf1[i + 8] == 0) & (buf1[i + 9] == 5)){errorstr = "命令" + cmdn.ToString() + "返回结果异常,字节数不对!!";pictureBox_Normal.Image = Properties.Resources.异常;label_Right.Text = "异常";label_Hint.Text = errorstr;}}}}#endregion#region 查询命令通用帧头设置private void cmdHeadInit() //初始化命令帧头,只有在获取到设备信息后才会有此标志为1{for (int i = 0; i < 8; i++){cmdHead[i] = 0xff;}cmdHead[8] = 0x82;cmdHead[9] = Convert.ToByte( manufacID);cmdHead[9] |=0x80;cmdHead[10] = Convert.ToByte(devType);for (int i = 0; i < 3; i++){cmdHead[i + 11] = Convert.ToByte(devID[i]);}cmdHeadInitFlag = 1;}#endregion#region 命令1返回值解析(主变量PV)//命令1返回值解析//预期返回值为:FF FF FF FF FF FF FF FF 86 #add1 #add2 #add3 #add4 #add5 0x01 0x05 00 00 #0 #1...#4// ///////*********前导符*****///定界符//**************地址********//命令//数据长度//状态//主变量单位代码//主变量private void hartGetCmd1(){int n = serial_hart.BytesToRead;byte[] buf;byte cmdn = 1;byte datanum = 5;if (n > 18){buf = new byte[n];serial_hart.Read(buf, 0, n);findFrameHead(buf, cmdn, datanum);if (headFindFlag == 1){PVUnitCd = buf[headbegin + 10];PVValue = BitConverter.ToSingle(buf, headbegin + 11);hartGetCmdOk[1] = 1;headFindFlag = 0;headbegin = 0;}else{hartSendCmd1();}}}#endregion#region 命令2返回值解析(主变量电流值和百分比)//命令2返回值解析//预期返回值为:FF FF FF FF FF FF FF FF 86 #add1 #add2 #add3 #add4 #add5 0x02 0x18 00 00 #0..#3 #4...#7// ///////*******8个前导符*****///定界符//*********5字节地址********//命令//数据长度//状态//主变量电流//主变量量程百分比private void hartGetCmd2(){int n = serial_hart.BytesToRead;byte[] buf;byte cmdn = 2;byte datanum = 8;if (n > 18){buf = new byte[n];serial_hart.Read(buf, 0, n);findFrameHead(buf, cmdn, datanum);if (headFindFlag == 1){PVCurrent = BitConverter.ToSingle(buf, headbegin + 10);PVPercentRange = BitConverter.ToSingle(buf, headbegin + 14);hartGetCmdOk[2] = 1;headFindFlag = 0;headbegin = 0;}else{hartSendCmd2();}}}#endregion#region 命令3返回值解析(主变量电流和动态变量)//命令3返回值解析//预期返回值为:FF FF FF FF FF FF FF FF 86 #add1 #add2 #add3 #add4 #add5 0x03 0x18 00 00 #0..#3 #4// ///////*******8个前导符*****///定界符//*********5字节地址********//命令//数据长度//状态//主变量电流//主变量单位代码// #5...#8 #9 #10...#13 #14 #15...#18 #19 #20...#23//主变量值*第二变量代码*第二变量值*第三变量代码*第三变量值*第四变量代码*第四变量值private void hartGetCmd3(){int n = serial_hart.BytesToRead;byte[] buf;byte cmdn = 3;byte datanum = 24;if (n >34 ){buf = new byte[n];serial_hart.Read(buf, 0, n);findFrameHead(buf, cmdn, datanum);if (headFindFlag == 1){PVCurrent = BitConverter.ToSingle(buf, headbegin + 10);PVUnitCd = buf[headbegin + 14];PVValue = BitConverter.ToSingle(buf, headbegin + 15);SecVUnitCd = buf[headbegin + 19];SecVValue = BitConverter.ToSingle(buf, headbegin + 20);ThirdVUnitCd = buf[headbegin + 24];ThirdVValue = BitConverter.ToSingle(buf, headbegin + 25);ForthVUnitCd = buf[headbegin + 29];ForthVValue = BitConverter.ToSingle(buf, headbegin + 30);hartGetCmdOk[3] = 1;headFindFlag = 0;headbegin = 0;}else{hartSendCmd3();}}}#endregion#region 命令12返回值解析(设备消息)//该命令用于读取设备消息// //预期返回值为:FF FF FF FF FF FF FF FF 86 #add1 #add2 #add3 #add4 #add5 0x0C 0x18 00 00 #0..#23// ////*******8个前导符*****///定界符//*********5字节地址********//命令//数据长度//状态//设备消息(ASCII)private void hartGetCmd12(){int n = serial_hart.BytesToRead;byte[] buf;byte cmdn = 12;byte datanum ;if (n > 18){buf = new byte[n];serial_hart.Read(buf, 0, n);datanum = Convert.ToByte(n-18); //是24还是实际字符串长度不确定findFrameHead(buf, cmdn, datanum);if (headFindFlag == 1){StringBuilder strb = new StringBuilder();for (int i = 0; i < datanum; i++){strb.Append((char)buf[headbegin + 10 + i]);}hartMsg = strb.ToString();hartGetCmdOk[4] = 1;headFindFlag = 0;headbegin = 0;}else{hartSendCmd12();}}}#endregion#region 命令13返回值解析(标签描述)//命令3返回值解析//预期返回值为:FF FF FF FF FF FF FF FF 86 #add1 #add2 #add3 #add4 #add5 0x0D 0x18 00 00 #0..#5 #6...#17// ///////*******8个前导符*****///定界符//*********5字节地址********//命令//数据长度//状态//设备的Tag//描述符// #18...#20// 日期:日月年private void hartGetCmd13(){int n = serial_hart.BytesToRead;byte[] buf;byte cmdn = 13;byte datanum=21;if (n >31){buf = new byte[n];serial_hart.Read(buf, 0, n);findFrameHead(buf, cmdn, datanum);if (headFindFlag == 1){StringBuilder strb = new StringBuilder();for (int i = 0; i < 6; i++){strb.Append((char)buf[headbegin + 10 + i]);}hartTag = strb.ToString();strb.Clear();for (int i = 6; i < 18; i++){strb.Append((char)buf[headbegin + 10 + i]);}hartDspt = strb.ToString();hartDate = buf[headbegin + 20].ToString() + "年" +buf[headbegin + 19].ToString() + "月" +buf[headbegin + 18].ToString() + "日";hartGetCmdOk[5] = 1;headFindFlag = 0;headbegin = 0;}else{hartSendCmd13();}}}#endregion#region 命令14返回值解析(主变量传感器信息)//命令14返回值解析//预期返回值为:FF FF FF FF FF FF FF FF 86 #add1 #add2 #add3 #add4 #add5 0x0E 0x10 00 00 #0..#2 #3// ///////*******8个前导符*****///定界符//*********5字节地址********//命令//数据长度//状态//传感器序列号//单位代码// #4...#7 #8...#11 #12...#15// 传感器上限*传感器下限*主变量最小精度private void hartGetCmd14(){int n = serial_hart.BytesToRead;byte[] buf;byte cmdn = 14;byte datanum = 16;if (n > 26){buf = new byte[n];serial_hart.Read(buf, 0, n);findFrameHead(buf, cmdn, datanum);if (headFindFlag == 1){PVSensNum = (buf[headbegin + 10] << 16) & 0xff0000 + (buf[headbegin + 11] << 8) & 0xff00 + buf[headbegin + 12];PVSensUnitCd = buf[headbegin + 13];PVUpSensLmt = BitConverter.ToSingle(buf, headbegin + 14);PVLowSensLmt = BitConverter.ToSingle(buf, headbegin + 18);PVMiniSpan = BitConverter.ToSingle(buf, headbegin + 22);hartGetCmdOk[6] = 1;headFindFlag = 0;headbegin = 0;}else{hartSendCmd14();}}}#endregion#region 命令15返回值解析(主变量输出信息)//命令15返回值解析//预期返回值为:FF FF FF FF FF FF FF FF 86 #add1 #add2 #add3 #add4 #add5 0x0F 0x10 00 00 #0 #1// ///////*******8个前导符*****///定界符//*********5字节地址********//命令//数据长度//状态//报警选择代码//传递功能代码// #2 #3...#6 #7...#10 #11..#14 #15 #16// 上下量程单位代码*主变量上限*主变量下限*阻尼值**写保护代码*发行商代码/*private int PVAlarmSelCd = 0; //主变量报警选择代码private int PVTransFuncCd = 0; //主变量传递功能代码private int PVRangeUnitCd = 0; //主变量上下量程单位代码private float PVUpRangeValue = 0; //主变量上限值private float PVLowRangValue = 0;//主变量下限值private float PVDampValue = 0; //主变量阻尼值,单位秒private int WriteProtectCd = 251; //写保护代码private int PLDCd = 18; //商标发行商代码,18-ABB公司*/private void hartGetCmd15(){int n = serial_hart.BytesToRead;byte[] buf;byte cmdn = 15;byte datanum = 17;if (n > 27){buf = new byte[n];serial_hart.Read(buf, 0, n);findFrameHead(buf, cmdn, datanum);if (headFindFlag == 1){PVAlarmSelCd = buf[headbegin + 10];PVTransFuncCd = buf[headbegin + 11];PVRangeUnitCd = buf[headbegin + 12];PVUpRangeValue = BitConverter.ToSingle(buf, headbegin + 13);PVLowRangValue = BitConverter.ToSingle(buf, headbegin + 17);PVDampValue = BitConverter.ToSingle(buf, headbegin + 21);WriteProtectCd = buf[headbegin + 25];PLDCd = buf[headbegin + 26];hartGetCmdOk[7] = 1;headFindFlag = 0;headbegin = 0;}else{hartSendCmd15();}}}#endregion#region 命令16返回值解析(最终装配号)//命令15返回值解析//预期返回值为:FF FF FF FF FF FF FF FF 86 #add1 #add2 #add3 #add4 #add5 0x0F 0x10 00 00 #0 #1// ///////*******8个前导符*****///定界符//*********5字节地址********//命令//数据长度//状态//报警选择代码//传递功能代码// #2 #3...#6 #7...#10 #11..#14 #15 #16// 上下量程单位代码*主变量上限*主变量下限*阻尼值**写保护代码*发行商代码private void hartGetCmd16(){int n = serial_hart.BytesToRead;byte[] buf;byte cmdn = 16;byte datanum = 3;if (n > 27){buf = new byte[n];serial_hart.Read(buf, 0, n);findFrameHead(buf, cmdn, datanum);if (headFindFlag == 1){FinalAssembleNum = buf[headbegin + 10] * 65536 + buf[headbegin + 11]* 256 + buf[headbegin + 12];hartGetCmdOk[8] = 1;headFindFlag = 0;headbegin = 0;}else{hartSendCmd16();}}}#endregionprivate void hartSaveConstantTable() //常量存入常量表{DataRow hartc = hartConstant.NewRow();hartc["ID"] = IDHartConstant;hartc["Time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");hartc["制造商ID"] = manufacID;hartc["制造商设备类型"] = devType;hartc["通用命令文档版本号"] = cmdVersion;hartc["设备软件版本号"] = sfVersion;hartc["设备硬件版本号"] = hwVersion;hartc["设备ID号"] = devID;hartc["设备消息"] = hartMsg;hartc["标签Tag"] = hartTag;hartc["描述符"] = hartDspt;hartc["日期"] = hartDate;hartc["传感器序列号"] = PVSensNum;hartc["传感器上下限单位代码"] = PVSensUnitCd;hartc["传感器上限"] = PVUpSensLmt;hartc["传感器下限"] = PVLowSensLmt;hartc["主变量最小精度"] = PVMiniSpan;hartc["报警选择代码"] = PVAlarmSelCd;hartc["传递功能代码"] = PVTransFuncCd;hartc["上下量程值代码"] = PVRangeUnitCd;hartc["主变量上限值"] = PVUpRangeValue;hartc["主变量下限值"] = PVLowRangValue;hartc["主变量阻尼值"] = PVDampValue;hartc["写保护代码"] = WriteProtectCd;hartc["最终装配号"] = PLDCd;hartConstant.Rows.Add(hartc);}private void strHartCSet(StringBuilder str) //字符串赋值{str.Append("ID,");str.Append("Time,");str.Append("制造商ID,");str.Append("制造商设备类型,");str.Append("通用命令文档版本号,");str.Append("设备软件版本号,");str.Append("设备硬件版本号,");str.Append("设备ID号,");str.Append("设备消息,");str.Append("标签Tag,");str.Append("描述符,");str.Append("日期,");str.Append("传感器序列号,");str.Append("传感器上下限单位代码,");str.Append("传感器上限,");str.Append("传感器下限,");str.Append("主变量最小精度,");str.Append("报警选择代码,");str.Append("传递功能代码,");str.Append("上下量程值代码,");str.Append("主变量上限值,");str.Append("主变量下限值,");str.Append("主变量阻尼值,");str.Append("写保护代码,");str.Append("最终装配号");}public int[] hartViewItemSct = new int[6];/* private string[] hartConstItem = { "ID", "Time", "制造商ID", "制造商设备类型", "通用命令文档版本号","设备软件版本号", "", "", "", "","", "", "", "", "","", "", "", "", "","", "", "", "", "",};*/private void strHartDSet(StringBuilder str){str.Append("ID,");str.Append("Time,");str.Append("设备ID号,");str.Append("主变量单位代码,");str.Append("主变量值,");str.Append("主变量电流,");str.Append("主变量量程百分比,");str.Append("第二变量单位代码,");str.Append("第二变量值,");str.Append("第三变量单位代码,");str.Append("第三变量值,");str.Append("第四变量单位代码,");str.Append("第四变量值");}private void hartSaveConstantDb() //常量存入数据库{if (hartConstant.Rows.Count > 0){StringBuilder strHartC = new StringBuilder();strHartCSet(strHartC); //字符串赋值string saveStr = strHartC.ToString();int m = hartConstant.Rows.Count - 1;SqlCommand com = new SqlCommand(String.Format("insert into HartConstant('{0}')Values({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})", saveStr, hartConstant.Rows[m]["ID"], hartConstant.Rows[m]["Time"], hartConstant.Rows[m]["制造商ID"],hartConstant.Rows[m]["制造商设备类型"], hartConstant.Rows[m]["通用命令文档版本号"],hartConstant.Rows[m]["设备软件版本号"], hartConstant.Rows[m]["设备硬件版本号"], hartConstant.Rows[m]["设备ID号"],hartConstant.Rows[m]["设备消息"], hartConstant.Rows[m]["标签Tag"],hartConstant.Rows[m]["描述符"], hartConstant.Rows[m]["日期"],hartConstant.Rows[m]["传感器序列号"], hartConstant.Rows[m]["传感器上下限单位代码"],hartConstant.Rows[m]["传感器上限"], hartConstant.Rows[m]["传感器下限"],hartConstant.Rows[m]["主变量最小精度"], hartConstant.Rows[m]["报警选择代码"],hartConstant.Rows[m]["传递功能代码"], hartConstant.Rows[m]["上下量程值代码"],hartConstant.Rows[m]["主变量上限值"], hartConstant.Rows[m]["主变量下限值"],hartConstant.Rows[m]["主变量阻尼值"], hartConstant.Rows[m]["写保护代码"],hartConstant.Rows[m]["最终装配号"]), dbcon);try{com.ExecuteNonQuery();}catch (Exception ex){MessageBox.Show(ex.Message);}}}private void hartSaveDynamicTable() //动态变量存入动态变量表{DataRow hartd = hartDynamic.NewRow();hartd["ID"] = IDHartDynamic;hartd["Time"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");hartd["设备ID号"] = devID;hartd["主变量单位代码"] = PVUnitCd;hartd["主变量值"] = PVValue;hartd["主变量电流"] = PVCurrent;hartd["主变量量程百分比"] = PVPercentRange;hartd["第二变量单位代码"] = SecVUnitCd;hartd["第二变量值"] = SecVValue;hartd["第三变量单位代码"] = ThirdVUnitCd;hartd["第三变量值"] = ThirdVValue;hartd["第四变量单位代码"] = ForthVUnitCd;hartd["第四变量值"] = ForthVValue;hartDynamic.Rows.Add(hartd);}private void hartSaveDynamicDb() //动态变量存入数据看{if (hartDynamic.Rows.Count > 0){StringBuilder strHartD = new StringBuilder();strHartDSet(strHartD); //字符串赋值string saveStr = strHartD.ToString();int m = hartDynamic.Rows.Count - 1;SqlCommand com = new SqlCommand(String.Format("insert into HartDynamic('{0}')Values ({1},'{2}',{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13})", saveStr, hartDynamic.Rows[m]["ID"], hartDynamic.Rows[m]["Time"], hartDynamic.Rows[m]["设备ID号"],hartDynamic.Rows[m]["主变单位代码"], hartDynamic.Rows[m]["主变量值"],hartDynamic.Rows[m]["主变量电流"], hartDynamic.Rows[m]["主变量量程百分比"],hartDynamic.Rows[m]["第二变量单位代码"], hartDynamic.Rows[m]["第二变量值"],hartDynamic.Rows[m]["第三变量单位代码"], hartDynamic.Rows[m]["第三变量值"],hartDynamic.Rows[m]["第四变量单位代码"], hartDynamic.Rows[m]["第四变量值"]), dbcon);try{com.ExecuteNonQuery();}catch (Exception ex){MessageBox.Show(ex.Message);}}}#region 存储常量(数据库、数据表)private void hartSaveConstant(){if (dbcon_flag == 1){if (dbconOpenNow == 0){dbconOpen();}string sqlquery = "select top 1 ID from HartConstant order by ID desc";try{SqlDataAdapter sda = new SqlDataAdapter(sqlquery, dbcon);DataSet ds = new DataSet();sda.Fill(ds);//把查询结果填充在ds里if (ds.Tables[0].Rows.Count == 1){IDHartConstant = Convert.ToInt32(ds.Tables[0].Rows[0][0]) + 1;}elseIDHartConstant = 0;}catch (Exception ex){MessageBox.Show(ex.Message);}hartSaveConstantTable();hartSaveConstantDb();if (dbconOpenNow == 1){dbconClose();}}else{if (hartConstant.Rows.Count > 0){IDHartConstant = Convert.ToInt32(hartConstant.Rows[hartConstant.Rows.Count - 1]["ID"]) + 1;}else{IDHartConstant = 0;}hartSaveConstantTable();}}#endregion#region 存储动态变量(数据库、数据表)private void hartSaveDynamic(){if (dbcon_flag == 1){if (dbconOpenNow == 0){dbconOpen();}string sqlquery = "select top 1 ID from HartDynamic order by ID desc";try{SqlDataAdapter sda = new SqlDataAdapter(sqlquery, dbcon);DataSet ds = new DataSet();sda.Fill(ds);//把查询结果填充在ds里if (ds.Tables[0].Rows.Count == 1){IDHartDynamic = Convert.ToInt32(ds.Tables[0].Rows[0][0]) + 1;}elseIDHartDynamic = 0;}catch (Exception ex){MessageBox.Show(ex.Message);}hartSaveDynamicTable();hartSaveDynamicDb();if (dbconOpenNow == 1){dbconClose();}}else{if (hartDynamic.Rows.Count > 0){IDHartDynamic = Convert.ToInt32(hartDynamic.Rows[hartDynamic.Rows.Count - 1]["ID"]) + 1;}else{IDHartDynamic = 0;}hartSaveDynamicTable();}}#endregionprivate int hartNum = 0; //HART收发计数器,偶数发查询命令,奇数解析设备返回数据private int hartCmdNum = 0; //控制HART发送解析具体命令private int hartInitFlag = 0; //Hart设备初始化标识private int hartWorkFlag = 0; //Hart设备工作标识private int hartSleepFlag = 0; //Hart设备暂停查询标识(两分钟查询一次变量)private int hartSleepNum = 0; //Hart设备休眠时间private int hartInitOkFlag = 0; //初始化完成标识,用于更新主界面常量相关的参数显示#region HART设备初始化,主要是查询设备标识及常量信息//HART初始化private void hartInit(){if ((hartNum % 2) == 0){#region 发送初始化需要的查询指令switch (hartCmdNum){case 0:hartSendCmd0();hartNum++;hartInitOkFlag = 0;break;case 12:。