亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? driveru.pas

?? omroln OPC 用delphi描述了同OMROLnOPC通訊的過程
?? PAS
?? 第 1 頁 / 共 5 頁
字號:
    FPortInfo: TCommPortInfo; //通信設備屬性
    FOPCComm: TOPCComm; //通訊操作對象
    FDriveStatus: Integer; //通信設備狀態
    FRefreshDataPnt: DWord; //查詢數據
    FCommStateChkPnt: DWord; //通訊狀態檢查
    FCommAddress: string; //通訊端口的

    //用于后臺調度的事件
    FInputHandler: TInputHandler; //接收端口數據到達事件通知對象
    FSendHandler: TInputHandler; //接收下發數據事件通知對象
    FSendEvent: THandle; //發送數據事件通知對象
    FLoopTimer: TTimerHandler; //輪詢檢測的定時器
    FWaitTimer: TTimerHandler; //等待應答的定時器
    FWaitCount: Integer; //等待應答次數
    FScheduler: TScheduler; //調度事件對象

    //發送數據緩沖區
    FWindow: TSlidingWindow; //發送數據滑動窗口
    FAddressParse: TAddressParse; //設備變量的尋址對象

    function GetPortId: DWord;
    function SendPktToComm(WriteData: Variant; Address: string): Boolean;
    procedure SetDriveStatus(Value: Integer);
    procedure CheckReSendTime;
    procedure NotifyToSendPkt;
    function SendApplicationFrm(Frm: TFrame): Boolean;
    function GeneralWriteData(const LocalIndex: Integer; Value: Variant;
      var Info: TAppDataInfo): Boolean;
  protected
    function SendNextDataPacket: Boolean;
    procedure ReceiveCommData;
    procedure QueryCommData;

    //有關事件調度的函數
    procedure StartInputHandler;
    procedure StartSendHandler;
    procedure StartLoopTimer;
    procedure StartWaitTimer;

    procedure StopInputHandler;
    procedure StopSendHandler;
    procedure StopLoopTimer;
    procedure StopWaitTimer;
  public
    constructor Create(PortInfo: TCommPortInfo);
    destructor Destroy; override;
    procedure EventCallback(EventId: Integer); override;
    procedure StartDriver; //啟動驅動
    procedure StopDriver; //停止驅動
    function SendData(const LocalIndex: Integer; Value: Variant): Boolean;
  published
    property PortId: DWord read GetPortId;
    property Status: Integer read FDriveStatus;
    property CommAddress: string read FCommAddress;
  end;

  //通信設備列表類
  TDriverList = class(TObjectList)
  private
    FEvent: THandle;
    procedure FreeResource;
  public
    constructor Create;
    destructor Destroy; override;
    procedure Add(const Driver: TDriver);
    procedure Delete(const Driver: TDriver);
    function GetDriver(const ID: DWord): TDriver;
    procedure StartDrivers;
    procedure StopDrivers;
    procedure SetTrgEvent;
    class function GetDriverList: TDriverList;
  published
    property Event: THandle read FEvent;
  end;

  function GetJobNo: Byte;

var
  gDriverList: TDriverList;
  gDeviceVarList: TDeviceVarList;
  gJobNo: Byte; //SCMS發送的任務號

implementation
{$IFDEF DEBUG}
uses
  OPC;
{$ENDIF}

//**************************************************************************
//                  類名:TAddressParse
//                  功能:設備變量地址解析
//**************************************************************************

{*
 *                函數名稱:ItemIsNull
 *                函數功能:判斷OPCITEM的名稱是否為空
 *                入口參數:1、ItemName: string。 OPCITEM名稱
 *                出口參數:無
 *                  返回值:True -- 該變量為空
 *}

function TAddressParse.ItemIsNull(ItemName: string): Boolean;
begin
  Result := False;
  if (Length(ItemName) = 0) or
    (AnsiPos(CONST_NULL_ITEMNAME, UpperCase(ItemName)) <> 0) then
    Result := True;
end;

{*
 *                函數名稱:SplitValue
 *                函數功能:根據地址信息拆分出指定設備變量的數據
 *                入口參數:1、DeviceVar: TDeviceVar。設備變量
 *                          2、DataPkt: TDataPacket。數據
 *                出口參數:1、Value: Variant。拆分出的數據
 *                  返回值:True -- 該變量有數據
 *}

function TAddressParse.SplitValue(const DeviceVar: TDeviceVar; DataPkt: Variant;
  var Value: Variant): Boolean;
begin
  try
    case DeviceVar.AddressInfo.dwDataSort of
      Const_DataSort_Sta
      : Value := Integer(DataPkt);
      Const_DataSort_Num
      : Value := Integer(DataPkt);
      Const_DataSort_Chr
      : Value := String(DataPkt);
      Const_DataSort_Bln
      : Value := Integer(StrToBool(String(DataPkt)));
      else
        Value := DataPkt;
    end;
    Result := True;
  except
    WriteDebugLog('在SplitValue函數中,根據變量的類型進行類型轉換時發生錯誤');
    Result := False;
  end;
end;

{*
 *                函數名稱:FindItems
 *                函數功能:根據地址信息查找設備變量的索引信息
 *                入口參數:1、Addr: TAddressInfo。設備變量地址信息
 *                出口參數:無
 *                  返回值:TIntegerArray。設備變量索引數組
 *}

function TAddressParse.FindItems(Addr: TAddressInfo): TIntegerArray;
var
  I, J, K: Integer;
begin
  SetLength(Result, 0);
  for I := 0 to High(FReadListInfos) do
  begin
    for J := 0 to High(FReadListInfos[I].rcdReadInfo) do
    begin
      if AnsiCompareText(Addr.dwReadItem, FReadListInfos[I].rcdReadInfo[J].szItemName) = 0 then
      begin
        SetLength(Result, Length(FReadListInfos[I].rcdReadInfo[J].arrVarList));
        for K := 0 to High(FReadListInfos[I].rcdReadInfo[J].arrVarList) do
          Result[K] := FReadListInfos[I].rcdReadInfo[J].arrVarList[K];
        Exit;
      end;
    end;
  end;
end;

{*
 *                函數名稱:FindCommErrorItems
 *                函數功能:獲得與指定通信端口關聯的設備通信故障變量索引
 *                入口參數:無
 *                出口參數:無
 *                  返回值:TIntegerArray。設備變量索引數組
 *}

function TAddressParse.FindCommErrorItems: TIntegerArray;
var
  I, Count: Integer;
begin
  Count := Length(FCommErrorInfos);
  SetLength(Result, Count);
  for I := 0 to Count - 1 do
    Result[I] := FCommErrorInfos[I].dwLocalIndex;
end;

{*
 *                函數名稱:FindRTUCommErrorItems
 *                函數功能:查找指定RTU連接設備通信故障變量索引
 *                入口參數:無
 *                出口參數:無
 *                  返回值:TIntegerArray。設備變量索引數組
 *}

function TAddressParse.FindRTUCommErrorItems(RTUNo: DWord): TIntegerArray;
var
  I, Count: Integer;
begin
  Count := Length(FCommErrorInfos);
  SetLength(Result, 0);
  for I := 0 to Count - 1 do
  begin
    if (FCommErrorInfos[I].rcdAddress.dwRTUNo = RTUNo) then
    begin
      SetLength(Result, Length(Result) + 1);
      Result[High(Result)] := FCommErrorInfos[I].dwLocalIndex;
    end;
  end;
end;

{*
 *                函數名稱:Create
 *                函數功能:構造函數
 *                入口參數:無
 *                出口參數:無
 *                  返回值:無
 *}

constructor TAddressParse.Create; 
begin
  InitializeCriticalSection(FLock);
  FRTUFaultList := TList.Create;
  SetLength(FSCMSFaultList, 0);
  SetLength(FCommErrorInfos, 0);
  SetLength(FNormalInfos, 0);
end;

{*
 *                函數名稱:Destroy
 *                函數功能:析構函數
 *                入口參數:無
 *                出口參數:無
 *                  返回值:無
 *}

destructor TAddressParse.Destroy;
begin
  FNormalInfos := nil;
  FCommErrorInfos := nil;
  FSCMSFaultList := nil;
  FRTUFaultList.Free;
  DeleteCriticalSection(FLock);
  inherited;
end;

{*
 *                函數名稱:AddInfo
 *                函數功能:增加設備變量的尋址信息
 *                入口參數:1、Info: TAddressParseInfo。設備變量運行信息
 *                出口參數:無
 *                  返回值:無
 *}

function TAddressParse.AddInfo(Info: TAddressParseInfo): Integer;
var
  I: Integer;
  FindIt: Boolean;
  WriteInfo: TWriteInfo;
begin
  EnterCriticalSection(FLock);
  try
    Result := -1;
    if Info.rcdAddress.dwDataType = Const_Type_CommErr then //通信故障的功能組
    begin
      SetLength(FCommErrorInfos, Length(FCommErrorInfos) + 1);
      FCommErrorInfos[High(FCommErrorInfos)] := Info;
      Result := -High(FNormalInfos);
    end;
    if not ItemIsNull(Info.rcdAddress.dwReadItem) then
    begin
      //將設備變量的讀地址信息添加到數組中
      SetLength(FNormalInfos, Length(FNormalInfos) + 1);
      FNormalInfos[High(FNormalInfos)] := Info;
      Result := High(FNormalInfos);
    end;
    if ItemIsNull(Info.rcdAddress.dwReadItem) then
    begin
      Result := -High(Integer);
    end;

    //將有效的OPCITEM名稱加入列表中
    FindIt := False;
    if not ItemIsNull(Info.rcdAddress.dwReadItem) then
    begin
      for I := 0 to High(FItemNameList) do
      begin
        if AnsiCompareText(FItemNameList[I], Info.rcdAddress.dwReadItem) = 0 then
        begin
          FindIt := True;
          Break;
        end;
      end;

      if not FindIt then
      begin
        SetLength(FItemNameList, Length(FItemNameList) + 1);
        FItemNameList[High(FItemNameList)] := Info.rcdAddress.dwReadItem;
      end;
    end;

    //將有效的OPCITEM名稱加入列表中
    FindIt := False;
    if not ItemIsNull(Info.rcdAddress.dwWriteItem) then
    begin
      for I := 0 to High(FItemNameList) do
      begin
        if AnsiCompareText(FItemNameList[I], Info.rcdAddress.dwWriteItem) = 0 then
        begin
          FindIt := True;
          Break;
        end;
      end;

      if not FindIt then
      begin
        SetLength(FItemNameList, Length(FItemNameList) + 1);
        FItemNameList[High(FItemNameList)] := Info.rcdAddress.dwWriteItem;
      end;
    end;

    //判斷變量是否需要定時下發
    if (Info.rcdAddress.dwFuncGroup = Const_FG_SYSTEM) and
      (Info.rcdAddress.dwDataType = Const_Type_RTUCommCheck) then
    begin
      if ItemIsNull(Info.rcdAddress.dwWriteItem) then
        Exit;

      FindIt := False;
      for I := 0 to High(FAutoWriteInfos) do
      begin
        if AnsiCompareText(FAutoWriteInfos[I].szItemName, Info.rcdAddress.dwWriteItem) = 0 then
        begin
          FindIt := True;
          Break;
        end;
      end;

      if FindIt then
        Exit;

      WriteInfo.szItemName := Info.rcdAddress.dwWriteItem;
      WriteInfo.dwWriteSample := Info.rcdAddress.dwSampleTime * 1000;
      WriteInfo.dwPriorWrite := 0;
      WriteInfo.dwWriteValue := 0;
      SetLength(FAutoWriteInfos, Length(FAutoWriteInfos) + 1);
      FAutoWriteInfos[High(FAutoWriteInfos)] := WriteInfo;
    end;
  finally
    LeaveCriticalSection(FLock);
  end;
end;

{*
 *                函數名稱:GetItemNameList
 *                函數功能:獲得數據項名稱的列表
 *                入口參數:無
 *                出口參數:無
 *                  返回值:數據項名稱列表
 *}

function TAddressParse.GetItemNameList: TStringArray;
var
  I: Integer;
begin
  SetLength(Result, Length(FItemNameList));
  for I := 0 to High(FItemNameList) do
    Result[I] := FItemNameList[I];
end;

{*
 *                函數名稱:FinishedAdd
 *                函數功能:完成添加設備變量的尋址信息
 *                          1、根據設備變量尋址信息中的讀地址進行排序
 *                          2、根據設備變量的尋址信息生成采樣周期判定數組
 *                入口參數:無
 *                出口參數:無
 *                  返回值:無
 *}

procedure TAddressParse.FinishedAdd;
var
  FindIt: Boolean;
  ReadInfo: TReadInfo;
  I, J, K, Idx, Count: Integer;
begin
  EnterCriticalSection(FLock);
  try
    SetLength(FReadListInfos, 0);
    Count := Length(FNormalInfos);
    if Count = 0 then
      Exit;

    for I := 0 to Count - 1 do
    begin
      //判斷處理的變量是否需要主動查詢
      if ItemIsNull(FNormalInfos[I].rcdAddress.dwReadItem) then

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
另类综合日韩欧美亚洲| 亚洲国产你懂的| 日韩一区二区三区视频在线| 色乱码一区二区三区88| 一本大道久久a久久精品综合| 国内精品伊人久久久久av一坑 | 亚洲乱码国产乱码精品精可以看| 欧美经典一区二区| 国产精品色在线观看| 国产精品久久久久久久浪潮网站| 亚洲欧美日本韩国| 亚洲综合av网| 蜜臀av性久久久久蜜臀aⅴ流畅| 蜜臀精品久久久久久蜜臀 | 2021国产精品久久精品| 久久亚洲精品小早川怜子| 久久亚洲精精品中文字幕早川悠里 | 国产网站一区二区| 国产精品黄色在线观看| 一个色妞综合视频在线观看| 亚洲成a人片综合在线| 精品一区二区成人精品| 成人免费视频caoporn| 欧洲一区在线电影| 日韩免费观看高清完整版在线观看| 精品久久国产字幕高潮| 亚洲欧美在线视频观看| 久久99精品久久久久婷婷| 丁香五精品蜜臀久久久久99网站 | 欧美一级淫片007| 国产午夜精品久久久久久久| 亚洲最大成人网4388xx| 精品一区二区成人精品| 欧美午夜精品电影| 久久婷婷国产综合国色天香| 亚洲蜜臀av乱码久久精品| 秋霞午夜av一区二区三区| 成人激情黄色小说| 8x福利精品第一导航| 国产欧美一区二区精品性色| 一区二区三区91| 国产黄人亚洲片| 欧美精三区欧美精三区 | 在线欧美日韩精品| 久久老女人爱爱| 天堂va蜜桃一区二区三区| 不卡一区中文字幕| 久久久久久久一区| 蜜臀久久99精品久久久久久9| 97精品超碰一区二区三区| 精品福利av导航| 五月综合激情网| 一本大道av一区二区在线播放| 日韩午夜在线播放| 一区二区三区影院| 国产99久久久国产精品潘金网站| 欧美日韩精品免费观看视频| 亚洲欧美色一区| 99re视频精品| 国产日韩欧美精品在线| 精品亚洲porn| 精品剧情在线观看| 日韩av网站免费在线| 欧美日韩精品一区二区三区四区 | 国产91精品在线观看| 精品乱人伦小说| 首页国产欧美日韩丝袜| 欧美日韩一区二区电影| 一区二区三区欧美久久| 一本色道久久综合亚洲aⅴ蜜桃 | 欧美午夜精品一区二区三区 | 日韩午夜激情视频| 视频一区在线视频| 91精品国产欧美一区二区| 视频在线观看一区二区三区| 欧美日韩一区二区三区四区五区| 亚洲国产日韩在线一区模特| 欧美三级在线看| 日韩在线一区二区| 日韩你懂的电影在线观看| 毛片基地黄久久久久久天堂| 日韩三级视频在线看| 九色porny丨国产精品| 久久先锋影音av鲁色资源网| 国产精品自拍网站| 国产精品第五页| 欧美午夜精品一区二区三区| 日韩激情在线观看| 久久蜜臀精品av| 不卡视频免费播放| 亚洲免费毛片网站| 欧美一区二区三区不卡| 韩国视频一区二区| 国产精品久久久久一区| 欧美怡红院视频| 蜜桃av一区二区三区电影| 国产午夜精品理论片a级大结局| 不卡的看片网站| 亚洲成人先锋电影| 国产精品国产三级国产有无不卡| 五月婷婷激情综合网| 欧美大片一区二区三区| 国产米奇在线777精品观看| 久久国产夜色精品鲁鲁99| 亚洲国产精品黑人久久久| 色婷婷国产精品综合在线观看| 亚洲va在线va天堂| 亚洲精品视频在线观看网站| 91精品国产综合久久香蕉麻豆| 国内精品在线播放| 亚洲一区二区四区蜜桃| 精品久久久久久无| 色综合天天做天天爱| 麻豆精品一二三| 日韩一区有码在线| 欧美一区二区三区四区高清| 成人性生交大合| 日韩专区在线视频| 1024成人网| 久久综合久久鬼色| 欧美日韩一本到| av动漫一区二区| 黑人精品欧美一区二区蜜桃| 亚洲高清一区二区三区| 国产欧美日韩精品一区| 欧美一区二区三区婷婷月色 | 亚洲午夜精品17c| 国产亚洲欧美日韩日本| 欧美一级黄色大片| 91成人国产精品| 99视频一区二区| 国产精品18久久久久久久久| 日韩国产欧美在线视频| 亚洲综合免费观看高清完整版在线| 久久久久久久久久久久久久久99| 欧美巨大另类极品videosbest| 91视视频在线观看入口直接观看www | 丁香婷婷综合网| 国产二区国产一区在线观看| 蜜桃传媒麻豆第一区在线观看| 亚洲国产成人av好男人在线观看| 中文字幕一区二区三区视频| 国产色产综合色产在线视频| 欧美第一区第二区| 欧美一区二区三区在| 日韩午夜在线影院| 日韩欧美在线123| 欧美成va人片在线观看| 欧美福利视频一区| 91精品国产91综合久久蜜臀| 欧美日韩在线三区| 777xxx欧美| 日韩一级二级三级| 日韩精品中文字幕一区二区三区| 日韩一区二区三区在线| 精品久久久久久无| 日本一二三不卡| 国产精品久久久久久久久搜平片 | 欧美高清视频不卡网| 制服视频三区第一页精品| 91麻豆精品国产综合久久久久久| 欧美剧在线免费观看网站 | av电影在线观看不卡| 色综合激情久久| 欧美美女黄视频| 欧美一区二区精美| 久久综合久色欧美综合狠狠| 欧美国产欧美亚州国产日韩mv天天看完整 | 艳妇臀荡乳欲伦亚洲一区| 亚洲制服欧美中文字幕中文字幕| 一级日本不卡的影视| 日本成人中文字幕| 高清不卡一区二区| 欧美综合一区二区| 欧美成人一区二区三区在线观看| www激情久久| 综合婷婷亚洲小说| 日韩激情视频网站| 国产福利91精品一区| 欧美专区日韩专区| 久久综合久色欧美综合狠狠| 亚洲欧洲另类国产综合| 亚洲成av人影院在线观看网| 国产在线一区观看| 欧美性感一类影片在线播放| 久久午夜国产精品| 亚洲午夜国产一区99re久久| 国产制服丝袜一区| 欧美视频中文一区二区三区在线观看| 日韩欧美在线观看一区二区三区| 日本一区二区三区免费乱视频| 亚洲在线免费播放| 国产精品99久久久久| 欧美三级日韩三级国产三级| 国产性天天综合网| 日韩精品色哟哟| 色视频欧美一区二区三区| 欧美成人官网二区| 首页国产欧美日韩丝袜| 色久优优欧美色久优优|