Einzelnen Beitrag anzeigen

DelphiManiac

Registriert seit: 5. Dez 2005
742 Beiträge
 
#18

Re: Dauert Sleep(1) auf allen Windows /Rechnersystemem 1ms?

  Alt 3. Aug 2007, 10:29
Meine Klasse Kommunikation hat folgende Methode:

Delphi-Quellcode:
function TKommunikation.Communicate(Order:TOrder; Adresse:TAdress;var Data:TDaten):Integer;
{ ************************* Kommunikationsmodul ************************** }
var
  Opened:integer; // Variable die den Zustand der Verbindung zeigt
  {*** Zählervariablen: **}
  iPolling : integer; // Variable zum Pollen der Schnittstelle
  iData : integer; // Variable für den Abbruch, falls die Daten falsch sind
  iTimeout : integer; // Variable für den TimeOut
  QBytes : integer; // Anzahl der Bytes am Port
  varcheckchecksum: integer;
  varcheckcommand : integer;
  varcheckAdressH : integer;
  varcheckAdressL : integer;
  varcheckData1 : integer;
  varcheckData2 : integer;
  varcheckData3 : integer;
  varcheckData4 : integer;
  dataOk : boolean;
  i : integer;
  res : DWord;
  tick : DWORD;
  TimeOut : DWORD;
  MilliSeconds : DWORD;
  _time: DWORD;
  _time1: DWORD;
  time1: Cardinal;
  time2: Cardinal;
Begin
// fCS.Enter; { Wechselseitger Ausschluss }
  //fCS.TryEnter;
// _time:= GetTickCount;

  if NOT(Assigned(Schnittstelle)) then
  begin
    result:=300;
    exit;
  end;
  if NOT(Schnittstelle.isConnected) then
  begin
    Result:=111;
    exit;
  end;
  dataOk:=true;
  varcheckcommand:=0;
  varcheckAdressH:=0;
  varcheckAdressL:=0;
  varcheckData1:=0;
  varcheckData2:=0;
  varcheckData3:=0;
  varcheckData4:=0;
  varcheckchecksum:=0;
  QBytes:=0;
  Opened:=0;
  iData:=1;
  iTimeOut:=0; // Timeout Variable wird mit 0 initialisiert
// Schnittstelle.FlushBufferIN; {Schnittstellenpuffer löschen}
// Schnittstelle.FlushBufferOut; {Schnittstellenpuffer löschen}
  //****************** Befehl wird gesetzt***********************//
  //Befehl zB.: ReadWord (RW) oder (WR) WriteRequest oder (RF) ReadFloat
  case Order of
    READ_WORD: ReadWord(Adresse.RS485Adress,Adresse.AdressHigh,Adresse.AdressLow);
    READ_BYTE: ReadByte(Adresse.RS485Adress,Adresse.AdressHigh,Adresse.AdressLow);
// READ_FLOAT: ReadFloat(Adresse.RS485Adress,Adresse.AdressHigh,Adresse.AdressLow);
    WRITE_WORD: WriteWord(Adresse.RS485Adress,Adresse.AdressHigh,Adresse.AdressLow,Data.Data1,Data.Data2);
    WRITE_BYTE: WriteByte(Adresse.RS485Adress,Adresse.AdressHigh,Adresse.AdressLow,Data.Data2);
// WRITE_FLOAT: WriteFloat(Adresse.RS485Adress,Adresse.AdressHigh,Adresse.AdressLow,Data.Data1,Data.Data2,Data.Data3,Data.Data4);
// WRITE_RESET: WriteReset(Adresse.RS485Adress);
    WRITE_REQUEST: WriteRequest(Adresse.RS485Adress);
  end;



  // ***********************************************************//
  repeat
    if Schnittstelle.GetQBytes >0 then
    begin
      Schnittstelle.FlushBufferIN; {Schnittstellen[eingangs]puffer löschen}
    end;
    Schnittstelle.SendBytes(7,fBufferOut); {Ausgangspuffer senden}
    iPolling:=1;
    repeat
      QBytes:=Schnittstelle.GetQBytes; // Bytes am Port
      Sleep(SLEEP_POLL_TIME); ////////////////////////////////// HIER wird gepolllt
       inc(iPolling);
    until ((QBytes =7) Or (iPolling >I_POLLING_MAX));
   if (QBytes=7) then
   begin
     Schnittstelle.ReceiveBytes(7,fBufferIn); {Schnittstelleneingang lesen}
     Result:=0;
     dataOk:=false;
     //*********** DATENÜBERPRÜFUNG************
     varcheckchecksum := Checkchecksum;
     varcheckcommand := CheckCommand;
     varcheckAdressH := CheckAdressH;
     varcheckAdressL := checkAdressL;
     //******************************************
     // Bei Schreibbefehlen muss der komplette Frame, der gesendet wurde
     // auch wieder zurückkommen
     if ((Order=WRITE_REQUEST)Or
          (Order=WRITE_RESET)Or
          (Order=WRITE_BYTE)Or
          (Order=WRITE_WORD)Or
          (Order=WRITE_FLOAT)) then
      begin
        if ((varcheckchecksum=0)
          and (varcheckcommand=0)
          and (varcheckAdressH=0)and (varcheckAdressL=0)) then
        begin
          dataOk:=true;
          inc(fCounts);
          result:=comOK; // Kommunikation i.O.
          if Assigned(fOnNewCount) then fOnNewCount(fCounts);
          exit
        end;
      end
      else
      begin
     // Bei den Lesebefehlen muss die Checksum + AdresseHigh+ AdresseLow stimmen
        If ((varcheckchecksum=0) and (varcheckcommand=0) and (varcheckAdressH=0) and (varcheckAdressL=0)) then
        begin
          dataOk:=true;
          result:=comOK; // Kommunikation i.O.
// _time1:= GetTickCount - _time;
// fDateiListe.Add('Polling:= '+IntToStr(iPolling));
// fDateiListe.Add('Time:= '+IntToStr(_time1));
// fDateiListe.SaveToFile('C:\Logdatei.txt');
// ShowMessage( IntToHex (fbufferIn[1],2) +' '+ IntToStr(_time1));
          Data.Data1 := fBufferIn[4];
          Data.Data2 := fBufferIn[5];
          Data.Data3 := fBufferIn[6];
          Data.Data4 := fBufferIn[7];
          inc(fCounts);
 // if Assigned(fOnNewCount) then begin fOnNewCount(fCounts); end;
          exit;
        end;
      end;
  end;
  inc(iTimeout);
until (iTimeout>=TIME_OUT_WAIT_COUNTS) Or (dataOk=False) ;
  if (iTimeout>=TIME_OUT_WAIT_COUNTS) then
  begin
    Result:=comTimeOut; // TimeOut verursacht
    if Assigned(OnTimeOut) then
    begin
      fOnTimeOut(Self);
    end;
// MessageDlg('TimeOut', mtError, [mbOk], 0); { TODO : TimeOut MessagDlg muss noch entfernt werden }
// Schnittstelle.Disconnect;
    exit;
  end
  else
  begin
    Result:=comBadData; // Fehler bei den angekommenen Daten
// MessageDlg('Fehler bei den angekommenen Daten', mtError, [mbOk], 0);{ TODO : BadData MessagDlg muss noch entfernt werden }
    fCS.Leave;
  end;
End;


Es gibt folgenden ablauf:

1.Senden
2.Warten
3.Überprüfen ob 7 Bytes da sind
--> JA dann 7 Bytes lesen und auf Gültigkeit prüfen
--> Nein Counter hochzählen weiter mit 3
wenn Counter > x
dann nochmal 1 und counter2 hochzählen (also nochmal senden)
irgendwann muss abgebrochen werden (nach dem 3. mal Senden beispielsweise..)

Gruß
  Mit Zitat antworten Zitat