Tech-Ecke / Delphi Inhalt / COM-Port ansteuern

 

     COM-Port ansteuern in Delphi


   COM-Port (RS232)

Im Gegensatz zum LPT-Port bietet der COM-Port weniger Ein- und Ausgänge, welche zum Steuern und Regeln genutzt werden können. Jedoch lässt er sich im Gegensatz zu einem LPT-Port einfach und günstig an modernen PC's, per USB-Adapter nachrüsten und mittels Schieberegister lassen sich die Ausgangsports auch beliebig erweitern.

Am COM-Port finden man drei nutzbare Ausgänge am Pin 3, 4 und 7 und vier nutzbare Eingänge am Pin 1, 6, 8 und 9. Der Ausgang TxD ist mit einem CH340/CH341 basierendem USB-COM-Adapter nicht möglich. Der Pin 9 "Ring Indicator" ist hier auch nur bedingt nutzbar. Einen High-Pegel (> +3V) quittiert er nur mit einem kurz gepulstem Signal. Wie lange ein Pegel ansteht lässt sich also nicht ermitteln. Mit meinem Prolific 2303GC USB-Adapter klappt das Auslesen wie bei den anderen Ausgängen und RI steht auch voll zur Verfügung.

     
1 DCD  [E] Data Carrier
2 RxD Receive Data (nicht direkt nutzbar für Hardwarebasteleien)
3 TxD  [A] Transmit Data (nicht nutzbar bei CH34x USB-Adapter) siehe hier
4 DTR  [A] Data Terminal Ready
5 GND Masse
6 DSR  [E] Data Set Ready
7 RTS  [A] Request to Send
8 CTS  [E] Clear to Send
9 RI  [E] Ring Indicator (nur bedingt nutzbar bei USB-Adapter mit CH34x-Chipset)

Weitere Infos und eine Testschaltung zum COM-Port gibt es hier


 

   Code

Sowohl für das Setzen der Ausgänge als auch das Lesen der Eingänge ist die globale Variable ComHandel zu setzen. Bei OnShow wird der Itemindex von CBCOMPort auf Null gesetzt und der COM-Port (hier COM 1) geöffnet under Handle in die Variable ComHandle übergeben. Nun könne über den Handle des die Eingänge gesetzt und die Ausgänge abgefragt werden.

Globale Variable ComHandle deklarieren:

 

 public
   { Public-Deklarationen }
   ComHandle: Integer;

 

z.B. bei OnShow oder auch per Button:

  CBCOMPort.ItemIndex := 0;
ComHandle := CreateFile('COM1',GENERIC_READ + GENERIC_WRITE,0,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL + FILE_FLAG_OVERLAPPED,0);
 

Auslesen der Eingänge:

Pin 1= (Status and MS_RLSD_ON), Pin 6 = (Status and MS_DSR_ON), Pin 9 =  (Status and MS_RING_ON)

  var
   Status: Dword;
   Wert: Integer
...

GetCommModemStatus(ComHandle,Status);
Wert := (Status and MS_CTS_ON) // Pin 8
Showmessage(IntToStr(Wert);
 
 

Setzen der Ausgänge:

  SetCommBreak(ComHandle); // Pin 3 (TxD) ein
EscapeCommFunction(ComHandle, SETDTR); // Pin 4 ein
EscapeCommFunction(ComHandle, SETRTS); // Pin 7 ein
 
  ClearCommBreak(ComHandle); // Pin 3 (TxD) aus
EscapeCommFunction(ComHandle, CLRDTR);
// Pin 4 aus
EscapeCommFunction(ComHandle, CLRRTS); // Pin 7 aus
 

z.B. bei OnClose oder auch per Button:

 

CloseHandle(ComHandle);

 


   Ausgänge erweitern mittels Schieberegister

Wie eingangs erwähnt lassen sich die Ausgänge des COM-Ports mit Schieberegisterbausteinen beliebig erweitern. Für das Schalten der Ausgänge kann folgende Procedure verwendet werden:

Hinweis: Bei Copy und Paste des Codes müssen COM-Port und 74HC595 wie folgt verdrahtet sein: RTS (7) = DS (14), DTR (4) = SHCP (11), TxD (3) = STCP (12). Mehr Infos dazu gibt's hier: Schieberegister.

  procedure SROut(ComHandle: Integer; ms, SRWert: Integer);
var
      i, z: Integer;
      aBit: array [0..7] of Integer;
begin
   z := 256;
   for i := 7 downto 0 do
      begin
         z := round(z /2);
         if SRWert >= z then begin SRWert := SRWert -z; aBit[i] := 1 end else aBit[i] := 0;
      end;
   for i := 7 downto 0 do
      begin
         EscapeCommFunction(ComHandle, CLRRTS);
         if aBit[i] = 1 then EscapeCommFunction(ComHandle, SETRTS);
         sleep(ms);
         EscapeCommFunction(ComHandle, SETDTR);
         sleep(ms);
         EscapeCommFunction(ComHandle, CLRDTR);
         EscapeCommFunction(ComHandle, CLRRTS);
          sleep(ms);
      end;
   SetCommBreak(ComHandle);
   sleep(ms);
   ClearCommBreak(ComHandle);
end;
 

Aufruf:

 

 SROut(ComHandle, 10, 255);   // alle 8 Ausgänge an
 SROut(ComHandle, 10, 0);   // alle 8 Ausgänge aus

 

Die Procedur setzt auf das oben gezeigte Code Beispiel auf. ComHandle ist also global deklariert, "10" setzt eine Wartezeit zwischen den einzelnen Signalen von 10 ms, "255" setz alle Ausgänge, "0" nimmt alles weg. Die Logik des SRWert folgt dem Setzen der Ausgänge des LPT-Ports in BASIC. Schön zu sehen in der COM-Port Demo Software.

Werden mehrere Schieberegister kaskadiert, so muss das Array aBit, die beiden Schleifen und der Eingangswert der Variable Z entsprechend angepasst werden. 

Die Option Drucken funktioniert erst ab Netscape V4.0 bzw. I-Explorer 5.0 !

[letzte Aktualisierung 25.01.2007]