?? driveru.pas
字號(hào):
{*
* 模塊名稱:OPC.OMRON設(shè)備驅(qū)動(dòng)程序的處理模塊
* 模塊功能:實(shí)現(xiàn)與外場(chǎng)設(shè)備的數(shù)據(jù)交互、協(xié)議解析
* 生成日期:2004/11/05
* 模塊作者:李杰
* 版本說明:1.0版
*}
unit DriverU;
interface
uses
Windows, Messages, SysUtils, Classes, Controls, Contnrs, Variants, Math, ExtCtrls, ComObj,
DrvIntfDefinesU, PubDefinesU, EventLogU, CommU;
const
//**************** 接口定義 ********************
gsDriverGUID = '{B66EE5D7-4152-4E47-9B67-2A68E638C388}'; //驅(qū)動(dòng)的標(biāo)識(shí)
gsModuleName = 'OPC.OMRON驅(qū)動(dòng)程序'; //DLL的描述
grcdDriverInfo: TDriverInfo = (cbSize: SizeOf(TDriverInfo);
szDriverName: gsModuleName; szDriverVer: '1.0'; szDriverDesc: gsModuleName;
szDriverGUID: gsDriverGUID; szFileName: 'OPC.DRV';
szCommPortParam: 'O:MachineName;ServerName;GroupName';
szCommPortParamDesc: 'O:[機(jī)器名];[OPC服務(wù)名];[分組名]';
szVariantParamDesc: '[RTU編號(hào)]+[讀變量]+[寫變量]';
szAddressConfigDesc: '[變量前綴]';
dwSampleTime: 1000; dwSyncTime: 0);
gCommPortAddressItemNumber = 1; //設(shè)備的地址信息
gDriverVariantItemNumber = 7; //設(shè)備變量中屬性元素的個(gè)數(shù)(RTU編號(hào) + 讀變量 + 寫變量)
//szVariantParam參數(shù)說明(例:1+52+1+1 功能組+數(shù)據(jù)類型+采集周期+數(shù)據(jù)種類)
//數(shù)據(jù)種類: 狀態(tài)-1、 數(shù)值-2、字符串-3
grcdDriverVariantInfo: array[0..46] of TDriverVarInfo = (
//(車輛檢測(cè)器)
(dwVariantId:90010001; szVariantDesc:'VD車流量'; szVariantParam:'001+052+60+02'),
(dwVariantId:90010002; szVariantDesc:'VD平均車速'; szVariantParam:'001+053+60+02'),
(dwVariantId:90010003; szVariantDesc:'VD占有率'; szVariantParam:'001+054+60+02'),
(dwVariantId:90011001; szVariantDesc:'VD故障'; szVariantParam:'001+001+00+01'),
(dwVariantId:90011002; szVariantDesc:'VD通信故障'; szVariantParam:'001+099+00+01'),
//(可變情報(bào)板)
(dwVariantId:90030001; szVariantDesc:'CSLS播放表'; szVariantParam:'004+047+00+03'),
(dwVariantId:90030002; szVariantDesc:'CMS播放表'; szVariantParam:'004+048+00+03'),
(dwVariantId:90030003; szVariantDesc:'開屏'; szVariantParam:'004+049+00+01'),
(dwVariantId:90030004; szVariantDesc:'關(guān)屏'; szVariantParam:'004+050+00+01'),
(dwVariantId:90031001; szVariantDesc:'控制器故障'; szVariantParam:'004+001+20+01'),
(dwVariantId:90031002; szVariantDesc:'顯示模組故障'; szVariantParam:'004+001+20+01'),
(dwVariantId:90031003; szVariantDesc:'顯示模組電源故障'; szVariantParam:'004+001+20+01'),
(dwVariantId:90031004; szVariantDesc:'單像素管故障'; szVariantParam:'004+001+20+01'),
(dwVariantId:90031005; szVariantDesc:'檢測(cè)系統(tǒng)故障'; szVariantParam:'004+001+20+01'),
(dwVariantId:90031006; szVariantDesc:'輸入交流電故障'; szVariantParam:'004+001+20+01'),
(dwVariantId:90031007; szVariantDesc:'防雷器故障'; szVariantParam:'004+001+20+01'),
(dwVariantId:90031008; szVariantDesc:'光敏部件故障'; szVariantParam:'004+001+20+01'),
(dwVariantId:90031009; szVariantDesc:'溫度異常故障'; szVariantParam:'004+001+20+01'),
(dwVariantId:90031010; szVariantDesc:'CMS通信故障'; szVariantParam:'004+099+00+01'),
//(照明控制系統(tǒng))
(dwVariantId:90040001; szVariantDesc:'光照強(qiáng)度數(shù)據(jù)'; szVariantParam:'194+048+60+02'),
(dwVariantId:90040002; szVariantDesc:'照明操作模式'; szVariantParam:'194+017+00+01'),
(dwVariantId:90040003; szVariantDesc:'照明控制級(jí)別'; szVariantParam:'194+065+00+01'),
(dwVariantId:90040004; szVariantDesc:'照明工作模式'; szVariantParam:'194+018+00+01'),
(dwVariantId:90041001; szVariantDesc:'照明設(shè)備自檢故障'; szVariantParam:'194+001+00+01'),
(dwVariantId:90041002; szVariantDesc:'照明設(shè)備通信故障'; szVariantParam:'194+099+00+01'),
//(通風(fēng)控制系統(tǒng))
(dwVariantId:90050001; szVariantDesc:'通風(fēng)操作模式'; szVariantParam:'195+017+00+01'),
(dwVariantId:90050002; szVariantDesc:'一氧化碳濃度'; szVariantParam:'195+048+60+02'),
(dwVariantId:90050003; szVariantDesc:'煙霧濃度'; szVariantParam:'195+049+60+02'),
(dwVariantId:90050004; szVariantDesc:'風(fēng)機(jī)運(yùn)行時(shí)間'; szVariantParam:'195+056+60+02'),
(dwVariantId:90050005; szVariantDesc:'風(fēng)機(jī)運(yùn)行狀態(tài)'; szVariantParam:'195+064+00+01'),
(dwVariantId:90050007; szVariantDesc:'風(fēng)機(jī)手動(dòng)控制'; szVariantParam:'195+065+00+01'),
(dwVariantId:90050008; szVariantDesc:'隧道內(nèi)風(fēng)速'; szVariantParam:'195+051+60+02'),
(dwVariantId:90050009; szVariantDesc:'隧道內(nèi)風(fēng)向'; szVariantParam:'195+052+60+02'),
(dwVariantId:90051001; szVariantDesc:'通風(fēng)設(shè)備自檢故障'; szVariantParam:'195+001+00+01'),
(dwVariantId:90051002; szVariantDesc:'通風(fēng)設(shè)備通信故障'; szVariantParam:'195+099+00+01'),
//(火災(zāi)告警系統(tǒng))
(dwVariantId:90060001; szVariantDesc:'區(qū)段自動(dòng)火災(zāi)報(bào)警'; szVariantParam:'196+048+00+01'),
(dwVariantId:90060002; szVariantDesc:'區(qū)段手動(dòng)火災(zāi)報(bào)警'; szVariantParam:'196+064+00+01'),
(dwVariantId:90061001; szVariantDesc:'火災(zāi)設(shè)備自檢故障'; szVariantParam:'196+001+00+01'),
(dwVariantId:90061002; szVariantDesc:'火災(zāi)設(shè)備通信故障'; szVariantParam:'196+099+00+01'),
//(交通控制系統(tǒng))
(dwVariantId:90070001; szVariantDesc:'交通操作模式'; szVariantParam:'212+017+00+01'),
(dwVariantId:90070003; szVariantDesc:'信號(hào)燈狀態(tài)'; szVariantParam:'212+064+00+01'),
(dwVariantId:90070004; szVariantDesc:'交通控制方案'; szVariantParam:'212+065+00+02'),
(dwVariantId:90071001; szVariantDesc:'交通設(shè)備自檢故障'; szVariantParam:'212+001+00+01'),
(dwVariantId:90071002; szVariantDesc:'交通設(shè)備通訊故障'; szVariantParam:'212+099+00+01'),
//RTU通訊狀態(tài)
(dwVariantId:90080001; szVariantDesc:'RTU通訊狀態(tài)'; szVariantParam:'254+078+00+01'),
(dwVariantId:90080002; szVariantDesc:'RTU通訊保持'; szVariantParam:'254+254+60+02'),
(dwVariantId:90080003; szVariantDesc:'RTU門開報(bào)警'; szVariantParam:'254+002+00+04'));
//************************************************
CONST_NULL_ITEMNAME = 'NULL';
Const_TIME_COMMFAILED = 600000; //10分鐘
Const_TIME_REFRESHDATA = 300000; //5分鐘
Const_RTUCOMM_NORMAL = 0;
//==========================================
//幀類型
Const_FrameType_Invalid = 0; //無效數(shù)據(jù)幀
Const_FrameType_Normal = 1; //普通數(shù)據(jù)幀
Const_FrameType_SCMS = 2; //CMS、CSLS數(shù)據(jù)幀
//==========================================
Const_Event_SendDataReq = 101; //發(fā)送數(shù)據(jù)
Const_Event_RecvDataInd = 102; //接收數(shù)據(jù)
Const_Event_LoopCheck = 103; //查詢數(shù)據(jù)
Const_Event_WaitAnswer = 104; //等待應(yīng)答數(shù)據(jù)(針對(duì)SCMS)
Const_FrameSendTimeOut = 5000; //發(fā)送超時(shí)時(shí)間(5秒)
Const_FrameSendFailed = 20000; //發(fā)送失敗檢測(cè)時(shí)間(20秒)
Const_DataSort_Sta = 1; //狀態(tài)數(shù)據(jù)
Const_DataSort_Num = 2; //數(shù)值數(shù)據(jù)
Const_DataSort_Chr = 3; //字符串
Const_DataSort_BLN = 4; //布爾型
//功能組描述
Const_FG_TRF = 1; //交通功能組
Const_FG_SCMS = 4; //情報(bào)板功能組
Const_FG_LIGHT = 194; //照明控制功能組
Const_FG_Ven = 195; //通風(fēng)控制功能組
Const_FG_FIRE = 196; //火災(zāi)功能組
Const_FG_BAS90 = 212; //交通控制功能組
Const_FG_SYSTEM = 254; //系統(tǒng)功能組
//==========================================
//數(shù)據(jù)類型描述
//公用數(shù)據(jù)類型
Const_Type_Error = 1; //設(shè)備故障
Const_Type_CommErr = 99; //通信故障類型
Const_Type_Mode = 17; //操作模式的類型
//VD數(shù)據(jù)類型
Const_Type_VDTrf = 52; //VD車流量數(shù)據(jù)
Const_Type_VDSpd = 53; //VD車速數(shù)據(jù)
Const_Type_VDHld = 54; //VD占有率數(shù)據(jù)
//情報(bào)板數(shù)據(jù)類型
Const_Type_CSLSLST = 47; //限速標(biāo)志播放表
Const_Type_CMSLST = 48; //情報(bào)板播放表
Const_Type_OPENSCN = 49; //開屏
Const_Type_CLOSESCN = 50; //關(guān)屏
//照明數(shù)據(jù)類型
Const_Type_BrtValue = 48; //照明強(qiáng)度數(shù)據(jù)
Const_Type_BrtLevel = 65; //照明級(jí)別
//通風(fēng)數(shù)據(jù)類型
Const_Type_COValue = 48; //CO濃度
Const_Type_VIValue = 49; //VI濃度
Const_Type_FANTime = 56; //風(fēng)機(jī)運(yùn)行時(shí)間
Const_Type_FANState = 64; //風(fēng)機(jī)運(yùn)行狀態(tài)
Const_Type_FANManu = 65; //風(fēng)機(jī)手動(dòng)控制
Const_Type_WindSpd = 51; //風(fēng)速數(shù)據(jù)
Const_Type_WindDct = 52; //風(fēng)向數(shù)據(jù)
//火災(zāi)數(shù)據(jù)類型
Const_Type_FireAuto = 48; //火災(zāi)自動(dòng)報(bào)警
Const_Type_FireManu = 64; //火災(zāi)手動(dòng)報(bào)警
//交通控制數(shù)據(jù)類型
Const_Type_TrfProgram = 65; //交通控制方案
Const_Type_TrfLightSta = 64; //信號(hào)燈狀態(tài)
//系統(tǒng)功能組數(shù)據(jù)類型
Const_Type_RTUCommState = 78; //RTU通訊狀態(tài)
Const_Type_RTUCommCheck = 254; //RTU通訊檢查(自動(dòng)下發(fā)數(shù)據(jù))
//=================================
Const_Re_Error = -1; //函數(shù)返回失敗
Const_Re_OK = 0; //函數(shù)返回成功
Const_Re_Other = 1; //函數(shù)返回其他
type
TDeviceVar = class;
TDriver = class;
TDriverList = class;
TIntegerArray = array of Integer;
TDWordArray = array of DWord;
TStringArray = array of string;
//設(shè)備變量尋址信息
TAddressInfo = record
dwRTUNo: DWord; //RTU編號(hào)
dwReadItem: string[100]; //讀變量名稱
dwWriteItem: string[100]; //寫變量名稱
dwFuncGroup: DWord; //功能組
dwDataType: DWord; //數(shù)據(jù)類型
dwSampleTime: DWord; //采集周期(毫秒)
dwDataSort: DWord; //數(shù)據(jù)類別
end;
TAddressInfoArray = array of TAddressInfo;
//應(yīng)用數(shù)據(jù)結(jié)構(gòu)
TAppDataInfo = record
dwLocalIndex: Integer; //本地設(shè)備變量索引
rcdAddress: TAddressInfo; //設(shè)備變量的地址信息
AppData: Variant; //接收數(shù)據(jù)內(nèi)容
dtDateTime: TDateTime; //報(bào)文中的時(shí)間(或系統(tǒng)時(shí)間)
end;
TAppDataInfoArray = array of TAppDataInfo;
//設(shè)備變量的運(yùn)行信息
PAddressParseInfo = ^TAddressParseInfo;
TAddressParseInfo = record
dwDeviceVarId: DWord; //設(shè)備變量編號(hào)
dwLocalIndex: Integer; //該設(shè)備變量在本地的列表中的索引
rcdAddress: TAddressInfo; //設(shè)備變量地址信息
end;
TAddressParseInfoArray = array of TAddressParseInfo;
//讀取數(shù)據(jù)的地址信息
PReadInfo = ^TReadInfo;
TReadInfo = record
szItemName: string[50]; //數(shù)據(jù)項(xiàng)的名稱
arrVarList: TIntegerArray; //關(guān)聯(lián)到的設(shè)備變量的索引數(shù)組
dwReadSample: DWord; //采樣周期(毫秒)
dwPriorRead: DWord; //上一次讀取的時(shí)間
end;
TReadInfoArray = array of TReadInfo;
//自動(dòng)下發(fā)數(shù)據(jù)的地址信息
PWriteInfo = ^TWriteInfo;
TWriteInfo = record
szItemName: string[50]; //數(shù)據(jù)項(xiàng)的名稱
dwWriteSample: DWord; //采樣周期(毫秒)
dwPriorWrite: DWord; //上一次下發(fā)的時(shí)間
dwWriteValue: Word; //隨機(jī)數(shù)
end;
TWriteInfoArray = array of TWriteInfo;
//讀取數(shù)據(jù)的有效地址列表信息
PReadListInfo = ^TReadListInfo;
TReadListInfo = record
dwRTUNo: DWord; //RTU編號(hào)
bCommState: Boolean; //通訊狀態(tài)
rcdReadInfo: TReadInfoArray; //讀取數(shù)據(jù)的數(shù)組
end;
TReadListInfoArray = array of TReadListInfo;
//CMS通訊故障數(shù)據(jù)結(jié)構(gòu)
TCMSCommErrorInfo = record
szCMSName: string; //CMS的讀地址
dwCount: DWord; //連續(xù)中斷次數(shù)
bStatus: Boolean; //通訊狀態(tài)
end;
TCMSCommErrorInfoArray = array of TCMSCommErrorInfo;
//設(shè)備變量地址解析
TAddressParse = class(TObject)
private
FLock: TRTLCriticalSection;
FAutoWriteInfos: TWriteInfoArray; //自動(dòng)下發(fā)的數(shù)據(jù)項(xiàng)列表
FItemNameList: TStringArray; //保存有效的OPCITEM名稱信息
FRTUFaultList: TList; //保存RTU通訊中斷編號(hào)
FSCMSFaultList: TCMSCommErrorInfoArray; //保存限速標(biāo)志通訊中斷地址信息
FReadListInfos: TReadListInfoArray; //讀取數(shù)據(jù)的采樣列表(該列表按OPC ITEM唯一排序)
FNormalInfos: TAddressParseInfoArray; //正常節(jié)點(diǎn)的列表
FCommErrorInfos: TAddressParseInfoArray; //通信故障節(jié)點(diǎn)的列表
function ItemIsNull(ItemName: string): Boolean;
function SplitValue(const DeviceVar: TDeviceVar; DataPkt: Variant;
var Value: Variant): Boolean;
function FindItems(Addr: TAddressInfo): TIntegerArray;
function FindCommErrorItems: TIntegerArray;
function FindRTUCommErrorItems(RTUNo: DWord): TIntegerArray;
public
constructor Create;
destructor Destroy; override;
function AddInfo(Info: TAddressParseInfo): Integer;
function GetItemNameList: TStringArray;
procedure FinishedAdd;
procedure SetCommState(State: Boolean);
procedure SetRecvData(AppDataInfo: TAppDataInfo);
procedure GetQueryData(var ReadInfos: TReadInfoArray);
procedure GetWriteData(var WriteInfos: TWriteInfoArray);
procedure SetRTUFault(RTUNo: DWord; CommState: Boolean);
end;
TFrame = class(TObject)
private
FDataPkt: Variant; //數(shù)據(jù)內(nèi)容(數(shù)據(jù)幀的數(shù)據(jù)部分)
FAddrInfo: TAddressInfo; //數(shù)據(jù)的地址信息
FLocalIndex: Integer; //設(shè)備變量本地索引
FItemName: string; //訪問OPCITEM的名稱
FFrmType: Integer; //數(shù)據(jù)幀類型
FSending: Boolean; //是否發(fā)送
FNeedAck: Boolean; //是否需要回應(yīng)
FStarted: DWord; //開始發(fā)送的TICKCOUNT
FDeleted: Boolean; //是否刪除
FFormed: Boolean; //是否打包
public
constructor Create(DataPkt: Variant; Xmit: Boolean);
destructor Destroy; override;
procedure SetParams(const AddrInfo: TAddressInfo; LocalIndex: Integer = -1);
procedure FormFrame;
procedure Marked;
published
property DataPacket: Variant read FDataPkt;
property AddrInfo: TAddressInfo read FAddrInfo;
property LocalIndex: Integer read FLocalIndex;
property ItemName: string read FItemName;
property NeedAck: Boolean read FNeedAck;
property Sending: Boolean read FSending;
property Deleted: Boolean read FDeleted;
property FrmType: Integer read FFrmType;
property Started: DWord read FStarted;
end;
//滑動(dòng)窗口
TSlidingWindow = class(TObject)
private
FSyncObj: TRTLCriticalSection;
FFrameList: TStringList; //發(fā)送數(shù)據(jù)幀列表
function GetFrameCount: Integer;
procedure ClearFrames;
public
constructor Create;
destructor Destroy; override;
procedure AddFrame(Frm: TFrame);
procedure Reset;
procedure ProcessSendFailed(SendFrm: TFrame);
function ProcessSendTimeOut(var ItemNameList: TStringArray): TIntegerArray;
function ProcessRecvAnswer(RecvFrm: TFrame): Boolean;
function GetNextFrame: TFrame;
published
property FrameCount: Integer read GetFrameCount;
end;
//設(shè)備變量對(duì)象
TDeviceVar = class(TAutoRelease)
private
FOwner: TDriver; //所屬設(shè)備對(duì)象
FDeviceVarId: DWord; //設(shè)備變量編號(hào)
FDeviceVarState: Integer; //設(shè)備變量狀態(tài)
FDeviceVarType: Integer; //設(shè)備變量類型
FServerIndex: Integer; //服務(wù)端設(shè)備變量對(duì)象索引
FLocalIndex: Integer; //該設(shè)備變量在本地的列表中的索引
FAddressIndex: Integer; //設(shè)備變量在地址樹中的絕對(duì)位置
FAddressInfo: TAddressInfo; //為了獲得測(cè)試數(shù)據(jù)加入的
FLastSendData: Variant; //最后一次發(fā)送的數(shù)據(jù)內(nèi)容
FLastRecvData: Variant; //最后一次接收的數(shù)據(jù)內(nèi)容
procedure SetState(State: Integer);
public
constructor Create(AOwner: TDriver; Info: TAddressParseInfo);
destructor Destroy; override;
function GetTestValue(var Value: Variant): Boolean;
function SendData(Value: Variant; ATime: TDateTime): Boolean;
function RecvData(Value: Variant; ATime: TDateTime): Boolean;
published
property Owner: TDriver read FOwner;
property DeviceVarId: DWord read FDeviceVarId write FDeviceVarId;
property DeviceVarType: Integer read FDeviceVarType write FDeviceVarType;
property DeviceVarState: Integer read FDeviceVarState write SetState;
property ServerIndex: Integer read FServerIndex write FServerIndex;
property LocalIndex: Integer read FLocalIndex;
property AddressIndex: Integer read FAddressIndex;
property AddressInfo: TAddressInfo read FAddressInfo;
property LastSendData: Variant read FLastSendData;
property LastRecvData: Variant read FLastRecvData;
end;
//設(shè)備變量列表對(duì)象
TDeviceVarList = class(TObjectList)
private
procedure FreeResource;
public
constructor Create;
destructor Destroy; override;
function AddItem(const DeviceVar: TDeviceVar): Integer;
function GetItem(const Index: Integer): TDeviceVar;
procedure MakeTestData;
class function AddrAnalyze(Src: String; var Dst: TAddressInfo): Boolean;
class function GetDeviceVarList: TDeviceVarList;
class function CreateDeviceVar(AOwner: TDriver; Info: TDeviceVarInfo): TDeviceVar;
end;
//通信設(shè)備類
TDriver = class(TLayer)
private
FSyncObj: TRTLCriticalSection; //發(fā)送數(shù)據(jù)時(shí)的同步對(duì)象
//串口屬性
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -