?? driveru.pas
字號(hào):
* 函數(shù)功能:根據(jù)設(shè)備變量編號(hào)和索引查找地址信息并生成發(fā)送數(shù)據(jù)
* 入口參數(shù):1、LocalIndex: Integer。地址索引信息
* 2、Value: Variant。發(fā)送數(shù)據(jù)
* 出口參數(shù):1、Info: TAppDataInfo。應(yīng)用數(shù)據(jù)信息
* 返回值:Boolean。執(zhí)行情況
*}
function TDriver.GeneralWriteData(const LocalIndex: Integer;
Value: Variant; var Info: TAppDataInfo): Boolean;
var
DeviceVar: TDeviceVar;
Data: string;
begin
Result := False;
DeviceVar := TDeviceVarList.GetDeviceVarList.GetItem(LocalIndex);
if not Assigned(DeviceVar) then
begin
WriteErrorLog(Format('下發(fā)數(shù)據(jù)時(shí)發(fā)生錯(cuò)誤!地址索引無(wú)效!(%d)', [LocalIndex]));
Exit;
end;
Data := Value;
Info.dwLocalIndex := LocalIndex;
Info.rcdAddress := DeviceVar.AddressInfo;
Info.AppData := Data;
Info.dtDateTime := Now;
Result := True;
end;
{*
* 函數(shù)名稱(chēng):CheckReSendTime
* 函數(shù)功能:檢查發(fā)送數(shù)據(jù)超時(shí)
* 入口參數(shù):無(wú)
* 出口參數(shù):無(wú)
* 返回值:無(wú)
*}
procedure TDriver.CheckReSendTime;
var
I: Integer;
VarList: TIntegerArray;
ItemNames: TStringArray;
DeviceVar: TDeviceVar;
begin
//超過(guò)一定時(shí)間沒(méi)有讀寫(xiě)操作則嘗試查詢(xún)
if GetTimeInterval(FRefreshDataPnt) >= Const_TIME_REFRESHDATA then
begin
FRefreshDataPnt := GetTickCount;
FOPCComm.RefershData;
end;
//檢查通訊是否中斷, 中斷后則嘗試重新打開(kāi)端口
if FOPCComm.CommStatus = Const_STATUS_DISCONNECT then
begin
ComObj.CoInitializeEx(nil, 0);
FOPCComm.StopComm;
FOPCComm.StartComm;
FOPCComm.RefershData;
end;
//超過(guò)規(guī)定的期限則認(rèn)為通訊中斷
if GetTimeInterval(FCommStateChkPnt) >= Const_TIME_COMMFAILED then
begin
FCommStateChkPnt := GetTickCount;
SetDriveStatus(COMM_STATUS_DISCONNECT);
end;
//先獲得發(fā)送數(shù)據(jù)幀列表
SetLength(VarList, 0);
//獲得超時(shí)設(shè)備變量索引列表 和 地址列表
VarList := FWindow.ProcessSendTimeOut(ItemNames);
//根據(jù)設(shè)備變量索引編號(hào)設(shè)置發(fā)送失敗
for I := Low(VarList) to High(VarList) do
begin
DeviceVar := TDeviceVarList.GetDeviceVarList.GetItem(VarList[I]);
if Assigned(DeviceVar) then
DeviceVar.SetState(ITEM_STATUS_SendFailed);
NotifyToSendPkt;
end;
end;
{*
* 函數(shù)名稱(chēng):NotifyToSendPkt
* 函數(shù)功能:通知調(diào)度對(duì)象發(fā)送數(shù)據(jù)
* 1、設(shè)置FSendEvent對(duì)象為有信號(hào)狀態(tài)
* 入口參數(shù):無(wú)
* 出口參數(shù):無(wú)
* 返回值:無(wú)
*}
procedure TDriver.NotifyToSendPkt;
begin
SetEvent(FSendEvent);
end;
{*
* 函數(shù)名稱(chēng):SendNextDataPacket
* 函數(shù)功能:從發(fā)送隊(duì)列中取出一個(gè)數(shù)據(jù),發(fā)送
* 1、發(fā)送成功
* 如果是無(wú)應(yīng)答數(shù)據(jù)幀,則認(rèn)定發(fā)送任務(wù)成功
* 如果是應(yīng)答數(shù)據(jù)幀,則等待接收數(shù)據(jù)
* 2、發(fā)送失敗
* 如果是無(wú)應(yīng)答數(shù)據(jù)幀,則認(rèn)定發(fā)送任務(wù)失敗
* 如果是應(yīng)答數(shù)據(jù)幀,則認(rèn)定發(fā)送任務(wù)失敗
* 入口參數(shù):無(wú)
* 出口參數(shù):無(wú)
* 返回值:True -- 發(fā)送成功
*}
function TDriver.SendNextDataPacket: Boolean;
var
Frm: TFrame;
DeviceVar: TDeviceVar;
begin
Result := False;
Frm := FWindow.GetNextFrame;
if Assigned(Frm) then
begin
Frm.FormFrame;
Result := SendPktToComm(Frm.DataPacket, Frm.ItemName);
if Result then //發(fā)送成功
begin
if (not Frm.NeedAck) and (Frm.LocalIndex >= 0) then
begin
DeviceVar := TDeviceVarList.GetDeviceVarList.GetItem(Frm.LocalIndex);
if Assigned(DeviceVar) then
DeviceVar.SetState(ITEM_STATUS_SendSuccess);
end;
end
else begin //發(fā)送失敗,則根據(jù)錯(cuò)誤碼判斷通訊中斷
FWindow.ProcessSendFailed(Frm);
if (Frm.LocalIndex >= 0) then
begin
DeviceVar := TDeviceVarList.GetDeviceVarList.GetItem(Frm.LocalIndex);
if Assigned(DeviceVar) then
DeviceVar.SetState(ITEM_STATUS_SendFailed);
end;
end;
NotifyToSendPkt;
end;
end;
{*
* 函數(shù)名稱(chēng):QueryCommData
* 函數(shù)功能:主動(dòng)查詢(xún)變量數(shù)據(jù)
* 入口參數(shù):無(wú)
* 出口參數(shù):無(wú)
* 返回值:無(wú)
*}
procedure TDriver.QueryCommData;
var
I, Count: Integer;
ItemName: string;
SendValue: Variant;
ItemNames: TStringArray;
ReadInfos: TReadInfoArray;
WriteInfos: TWriteInfoArray;
begin
//獲得當(dāng)前所有可以讀取的模擬量OPCITEM信息
SetLength(ReadInfos, 0);
SetLength(WriteInfos, 0);
FAddressParse.GetQueryData(ReadInfos);
Count := Length(ReadInfos);
if Count > 0 then
begin
SetLength(ItemNames, 0);
for I := 0 to Count - 1 do
begin
if FAddressParse.ItemIsNull(ReadInfos[I].szItemName) then
Continue;
SetLength(ItemNames, Length(ItemNames) + 1);
ItemNames[High(ItemNames)] := ReadInfos[I].szItemName;
end;
FOPCComm.QueryData(ItemNames);
end;
//查詢(xún)要自動(dòng)下發(fā)的數(shù)據(jù),并指定下發(fā)
FAddressParse.GetWriteData(WriteInfos);
Count := Length(WriteInfos);
if Count > 0 then
begin
for I := 0 to Count - 1 do
begin
if FAddressParse.ItemIsNull(WriteInfos[I].szItemName) then
Continue;
ItemName := WriteInfos[I].szItemName;
SendValue := WriteInfos[I].dwWriteValue;
FOPCComm.SendData(ItemName, SendValue);
end;
end;
end;
{*
* 函數(shù)名稱(chēng):ReceiveCommData
* 函數(shù)功能:從通訊端口讀取數(shù)據(jù)
* 獲得當(dāng)前所有可以讀取的地址信息
* 入口參數(shù):無(wú)
* 出口參數(shù):無(wú)
* 返回值:無(wú)
*}
procedure TDriver.ReceiveCommData;
var
ItemName: string; //數(shù)據(jù)項(xiàng)名稱(chēng)
ItemTime: TDateTime; //采集時(shí)間
ItemValue: Variant; //數(shù)據(jù)項(xiàng)的數(shù)值
AddrInfo: TAddressInfo;
AppDataInfo: TAppDataInfo;
begin
if not FOPCComm.ReadData(ItemName, ItemValue, ItemTime) then
Exit;
SetDriveStatus(COMM_STATUS_CONNECTED);
FRefreshDataPnt := GetTickCount;
FCommStateChkPnt := GetTickCount;
{$IFDEF DEBUG}
FrmOPC.AddPacket(Format('-->: 地址(%s). 數(shù)據(jù)(%s).', [ItemName, String(ItemValue)]));
WriteDebugLog(Format('-->: 服務(wù)(%s). 地址(%s). 數(shù)據(jù)(%s).', [FOPCComm.MachineName, ItemName, String(ItemValue)]));
{$ENDIF}
AddrInfo.dwReadItem := ItemName;
AppDataInfo.rcdAddress := AddrInfo;
AppDataInfo.AppData := ItemValue;
AppDataInfo.dtDateTime := ItemTime;
try
FAddressParse.SetRecvData(AppDataInfo);
except
WriteDebugLog('sss');
end;
end;
{*
* 函數(shù)名稱(chēng):StartInputHandler
* 函數(shù)功能:創(chuàng)建端口數(shù)據(jù)到達(dá)事件
* 入口參數(shù):無(wú)
* 出口參數(shù):無(wú)
* 返回值:無(wú)
*}
procedure TDriver.StartInputHandler;
begin
if Assigned(FInputHandler) then
Exit;
FInputHandler := TInputHandler.Create(Self, Self);
FInputHandler.InitEvent(FOPCComm.ReadEvent, Const_Event_RecvDataInd);
FScheduler.AddEventHandler(FInputHandler);
end;
{*
* 函數(shù)名稱(chēng):StartSendHandler
* 函數(shù)功能:創(chuàng)建發(fā)送數(shù)據(jù)事件
* 入口參數(shù):無(wú)
* 出口參數(shù):無(wú)
* 返回值:無(wú)
*}
procedure TDriver.StartSendHandler;
begin
if Assigned(FSendHandler) then
Exit;
FSendEvent := CreateEvent(nil, False, False, '');
FSendHandler := TInputHandler.Create(Self, Self);
FSendHandler.InitEvent(FSendEvent, Const_Event_SendDataReq);
FScheduler.AddEventHandler(FSendHandler);
end;
{*
* 函數(shù)名稱(chēng):StartLoopTimer
* 函數(shù)功能:?jiǎn)?dòng)定時(shí)讀數(shù)事件
* 入口參數(shù):無(wú)
* 出口參數(shù):無(wú)
* 返回值:無(wú)
*}
procedure TDriver.StartLoopTimer;
begin
FLoopTimer := TTimerHandler.Create(Self, Self);
FLoopTimer.InitEvent(Const_Event_LoopCheck, grcdDriverInfo.dwSampleTime, True);
FScheduler.AddEventHandler(FLoopTimer);
end;
{*
* 函數(shù)名稱(chēng):StartWaitTimer
* 函數(shù)功能:?jiǎn)?dòng)發(fā)送超時(shí)檢查事件
* 入口參數(shù):無(wú)
* 出口參數(shù):無(wú)
* 返回值:無(wú)
*}
procedure TDriver.StartWaitTimer;
begin
FWaitTimer := TTimerHandler.Create(Self, Self);
FWaitTimer.InitEvent(Const_Event_WaitAnswer, Const_FrameSendTimeOut, True);
FScheduler.AddEventHandler(FWaitTimer);
end;
{*
* 函數(shù)名稱(chēng):StopInputHandler
* 函數(shù)功能:釋放端口數(shù)據(jù)到達(dá)事件
* 入口參數(shù):無(wú)
* 出口參數(shù):無(wú)
* 返回值:無(wú)
*}
procedure TDriver.StopInputHandler;
begin
if not Assigned(FInputHandler) then
Exit;
FInputHandler.SetMarked;
FInputHandler := nil;
end;
{*
* 函數(shù)名稱(chēng):StopSendHandler
* 函數(shù)功能:釋放發(fā)送數(shù)據(jù)事件
* 入口參數(shù):無(wú)
* 出口參數(shù):無(wú)
* 返回值:無(wú)
*}
procedure TDriver.StopSendHandler;
begin
if not Assigned(FSendHandler) then
Exit;
FSendHandler.SetMarked;
FSendHandler := nil;
CloseHandle(FSendEvent);
end;
{*
* 函數(shù)名稱(chēng):StopLoopTimer
* 函數(shù)功能:停止輪詢(xún)檢查事件
* 入口參數(shù):無(wú)
* 出口參數(shù):無(wú)
* 返回值:無(wú)
*}
procedure TDriver.StopLoopTimer;
begin
try
if Assigned(FLoopTimer) then
begin
FLoopTimer.SetMarked;
FLoopTimer := nil;
end;
except
WriteDebugLog('停止輪詢(xún)讀數(shù)事件失敗!');
end;
end;
{*
* 函數(shù)名稱(chēng):StopWaitTimer
* 函數(shù)功能:停止發(fā)送超時(shí)檢查事件
* 入口參數(shù):無(wú)
* 出口參數(shù):無(wú)
* 返回值:無(wú)
*}
procedure TDriver.StopWaitTimer;
begin
try
if Assigned(FWaitTimer) then
begin
FWaitTimer.SetMarked;
FWaitTimer := nil;
FWaitCount := 0;
end;
except
WriteDebugLog('停止超時(shí)定時(shí)事件失敗!');
end;
end;
{*
* 函數(shù)名稱(chēng):Create
* 函數(shù)功能:構(gòu)造函數(shù)
* 入口參數(shù):1、PortInfo: TCommPortInfo。通信端口參數(shù)
* 出口參數(shù):無(wú)
* 返回值:無(wú)
*}
constructor TDriver.Create(PortInfo: TCommPortInfo);
var
Param: TCommParam;
begin
//初始化屬性
FPortInfo := PortInfo;
FDriveStatus := COMM_STATUS_UnKnown;
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -