Autor Beitrag
tmtmtm
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 22



BeitragVerfasst: Sa 28.08.04 03:14 
Hallo Leute!

Ich habe da mal eine wahrscheinlich dumme ;-) Frage zur Kommunikation mit COM-PORTS.

Und zwar versuche ich mit folgendem Code den COM1 zu öffnen, und ein paar Daten aus'm Port in einen Puffer zu laden: Aber diese kleine Test-Prozedur läuft net. Denn bei ReadFile gibt es einen heftigen Speicher-E/A-Fehler mit dem Inhalt "Zugriffsverletzung bei Adresse ...".
Was macht diese Prozedur falsch? (Ist leider nicht meine, sondern aus'm Netz.)
Denn auch meine eigene kleine Test-Prozedur (s.u.) kann nicht vom COM1 lesen, da sie dabei erst hängen bleibt und später abstürzt, obwohl der Port geöffnet ist.

Wer kann mir sagen, warum das Programm nicht von diesem Speicherbereich lesen kann? Ich krieg hier
noch graue Haare! :-( Schließlich hat's doch damals im ASM unter DOS auch geklappt.

Also wenn's jemand weiß - Bitte melden! "Danke" sag ich deshalb schon mal im Voraus.

Gruß T.M.

PS: Ich verwende WinXP & Delphi5
und: Ist es egal ob man das zu öffnende Gerät nun "COM1" oder "COM1:" nennt?

ausblenden volle Höhe Quelltext
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:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
procedure TForm1.Button1Click(Sender: TObject);
var 
  hCommFile : THandle; 
  TimeoutBuffer : PCOMMTIMEOUTS; 
  NumberOfBytesRead : dword; 
  Buffer : array[0..255] of char;
begin
// Gibt das Handle zum Port bzw. der Datei zurück
hCommFile := CreateFile(PChar('COM1'),
                        GENERIC_READ, //Hier evtl. einen anderen Parameter setzen
                        0,
                        nil,
                        OPEN_EXISTING,
                        FILE_ATTRIBUTE_NORMAL,
                        0);

if(hCommFile = INVALID_HANDLE_VALUE)then
  // Fehler; Kein gültiges Handle!


// Wenn man vom ComPort liest sollte man auch diese Zeilen benutzen.
// Wenn man darauf schreibt, sollt man auch noch WriteTotalTimeoutMultiplier und 

WriteTotalTimeoutConstant setzen
GetMem(TimeoutBuffer, sizeof(COMMTIMEOUTS));

GetCommTimeouts(hCommFile, TimeoutBuffer^);
TimeoutBuffer.ReadIntervalTimeout        := 100;
TimeoutBuffer.ReadTotalTimeoutMultiplier := 100;
TimeoutBuffer.ReadTotalTimeoutConstant   := 100;
SetCommTimeouts(hCommFile, TimeoutBuffer^);

FreeMem(TimeoutBuffer, sizeof(COMMTIMEOUTS));

// Schließlich lesen wir vom Port bzw. der Datei
FillChar(Buffer, sizeof(Buffer), #0);
ReadFile(hCommFile, Buffer, sizeof(Buffer), NumberOfBytesRead, nil);

// Das Handle zum Port bzw. der Datei wieder schließen,
// und sie somit wieder für andere Programme zugänglich machen.
CloseHandle(hCommFile);
end;


Meine eigene kleine Prozedur: Ohne Anschluss-Einstellungen und so. (Nur Stanard)

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
procedure TForm1.Button1Click(Sender: TObject);
Var F:File of Char;
    Res:Integer;
    C:Char;
begin
  FileMode:=0;
  AssignFile(F,'COM1');
  {$I-}
  Reset(F);
  {$I+}
  IF IOResult=0 Then
     Begin
       Read(F,C);  // hier kommt immer "Versuch hinter dem Dateiende zu lesen". D.h. keine Infos am Port???
       ShowMessage(C);
       CloseFile(F);
     End;
  FileMode:=2;
end;
.Chef
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1112



BeitragVerfasst: Sa 28.08.04 08:15 
tmtmtm hat folgendes geschrieben:
und: Ist es egal ob man das zu öffnende Gerät nun "COM1" oder "COM1:" nennt?

Natürlich nicht. Der Doppelpunkt muss mit hin. Und das wird auch der Grund sein, warums nicht geht.

Gruß,
Jörg
tmtmtm Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 22



BeitragVerfasst: Sa 28.08.04 12:54 
Titel: Habs so gemacht.
Danke Jörg! :-)

Jetzt kommt zumindest nicht mehr dieser dusselige Fehler mit dem Dateiende. Aber Das Programm geht trotzdem nach dem Lesebefehl "ReadFile" nicht weiter. Auch bei meiner eigenen kleinen Billig-Prozedur hängt er sich on einen Error-Raise auf. Der macht da einfach gar nix mehr. Aber Wieso??? :?:

MfG T.M.
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 28.08.04 14:11 
Titel: Re: Habs so gemacht.
tmtmtm hat folgendes geschrieben:
hängt er sich on einen Error-Raise auf. Der macht da einfach gar nix mehr. Aber Wieso???

Könnte man dir eventuell sagen, wenn du uns die Fehlermeldung auch nennst. :roll:
tmtmtm Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 22



BeitragVerfasst: Sa 28.08.04 14:41 
:lol: Sorry,

mit "on einen Error-Raise" meinte ich natürlich "ohne einen Error-Raise". Mein Fehler. ;-)

Der wahre Fehler ist: Es passiert nach dem "Lesen" einfach gar nichts mehr.
Das Programm parkt sich praktisch einfach ohne irgendwas zu tun. Sozusagen, wie als ob es auf irgendeine Aktion von seitens des Ports wartet. Kann das sein? Aber selbst wenn kein Signal anliegt sollte es doch trotzdem möglich sein, dieses "Nix-Signal" - welches ja auch einen Wert haben muss - zu empfangen. Oder seh ich das falsch?

Wieso geht das Programm nach dem Lese-Befehl net einfach weiter??? Habs schon auf 2 Rechnern getestet. (Mein eigener XP und 'n alter 98er) Dasselbe Ergebnis.

Was soll das?

Wenn's jemand weiß, dann bitte posten.
Denn ich lese hier auch nur die tollsten Erfahrungsberichte zum COM-Port. Wieso geht's bei mir net???


MfG T.M.
.Chef
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1112



BeitragVerfasst: Sa 28.08.04 20:49 
Warum dein unterer Code nicht geht, kann ich dir nicht sagen. Allerdings ist mir diese Art des Zugriffs auch etwas suspekt. Aber wenn du mit deinem oberen Code weitermachst, nimm mal die API-Funktion ReadFile zum auslesen. Das sollte funktionieren.
opfer.der.genauigkeit
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 754
Erhaltene Danke: 1



BeitragVerfasst: Sa 28.08.04 21:43 
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
// ReceiveText
function TSerial.ReceiveText;
// Text empfangen (Empfangspuffer leeren)
// Ergebnis: Eingelesener Text
var
  n, m: cardinal;
  Error: integer;
begin
  if FActive then begin
    n := BufRec;
    SetLength(Result, n);
    if not ReadFile(FSerHandle, Result[1], n, m, @Overlapped) then begin
      Error := GetLastError;
      if (Error = 0) then ;  // <-- Dummy wegen Compiler Warnung
    end;
  end else Result := '';
end;


Mußt du halt für deine Bedürfnisse umbauen.
Ist aus nem Programm von mir.

_________________
Stellen Sie sich bitte Zirkusmusik vor.
tmtmtm Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 22



BeitragVerfasst: So 29.08.04 03:02 
Super!!! Hammergeil!!!

Ich danke allen Beteiligten für die Super-Antworten!!!

Ihr habt mir sehr geholfen. Jetzt kann ich mit meiner Steuerungs-Geschichte fortsetzen. Fantastisch!!!

Danke natürlich besonders für den letzten Tip vom Opfer.der.Genauigkeit!!!
Es lag nur an diesem @Overlapped. Man muss also vorm Aufruf die Adresse einer Variable vom Typ "TOverlapped" als letzten Parameter bereitstellen, um die Funktion "ReadFile" im aktuellen Zusammenhang richtig auszuführen.

(Obwohl der COM nicht im "Overlapped"-Modus geöffnet wurde?(?!!?) Aber egal. Es läuft!!! Danke euch allen. Bis demnächst!!!

Und natürlich den Doppelpunkt hinterm COM net vergessen. ;-) Wieder was gelernt. Ist ja bei Windows mit allen Devices so.

Dankeschön!!!