![]() |
Probleme USB->Serial Converter
Hat irgendjemand eine Idee wie man die COM-Schnittstelle mit einem USB->Serial coverter ansteuern kann?
Bei einem "Normalen" COM-PORT hat der ja ne Adresse, aber wie mach ich das bei dem USB->Serial Converter? MFG Thomas |
Genauso!?
Der Converter stellt dir ein ganz normalen Comport zur Verfügung. Du steuerst den ganz normal an. Den rest(codierung für Usb) macht ja die Elektronik im Converter. Grüsse, Daniel :) |
Ja schon, aber wenn ich versuch den COM4 zu öffnen dann gibt er mir einen Fehler 1080 :(
Der Gerätemanager sagt der vituelle Com liegt auf COM4 Wenn ich den auf com2 leg und mein Prog. dann mit COM2 starte kommt der selbe Fehler (1080) MFG Thomas |
Da der USB-Serial Converter "nur" einen Treiber zur Verfügung stellt, kann auch nur über die Windows API und IOCTRL auf den virtuellen COM-Port zugegriffen werden. Ein direkter Hardwarezugriff über TurboPascal:Port[] ist nicht möglich, da das Gerät ja nicht wirklich existiert.
[edit] Wie öffnest bzw. greift du auf den COM-Port zu. [/edit] |
Wie mach ich den API zugriff denn?
|
Code:
Ich würde aber trotzdem gerne wissen, wie du das machst. Über eine Komponente, ... ?portname := '\\.\COM' + IntToStr(Integer(FPort)); FPortHandle := CreateFile(PChar(portname), // name of COM device to open GENERIC_READ or GENERIC_WRITE, // read-write access 0, nil, // not used OPEN_EXISTING, // required for tape devices 0, 0); // not used Denn eine Komponente kapselt normalerweise die API Aufrufe und greift auch nicht direkt auf die Ports zu. |
@jbg
Aber auch dieser virtuelle Port, hat ja im Gerätemanager eine Adresse. Wieso sollte er sie nicht ansprechen können? Nehmen wir mal eine ganz normale Kompo für Comports. Normalerweise machen sie ja auch nur diesen direkten HW-Zugriff. Ich kenn jetzt nciht alle, aber manche machen das so und manche warscheinlich anders. Was passiert nun, wenn man z.B. Com20 anspricht und da hängt so ein Converter dran? Grüsse, Daniel :) |
Ich hab die ELEKTOR genommen :D
Vielleicht kennt die ja jemand? Protinc.pas und port.dll |
wie ist denn:
Code:
deklariert?
portname
|
Bei uns an der Schule können wir die Software für unsere Roboter über einen USB-Serial-Converter mit Hilfe von CreateFile() und Co. ohne Probleme ansprechen.
|
Wenn das geht...
Ist ja klasse :D Aber wenn nicht :( Aber wie muss ich denn jetzt Portname deklarieren? |
portname ist ein String.
Ich habe nur einen sehr kleinen Ausschnitt von meinem Code gepostet. Eine zusätzliche DLL sagt mir aber, dass diese direkt auf den Port zugreift. Wenn du willst, kann ich auch die komplette Unit hier posten (ca. 170 Zeilen, von denen ich unnötiges entfernen kann). |
Die Unit greift ja nur auf die DLL zu...
In der sind alle DLL-Funktionen deklariert, damit man nicht in jedem Prog die DLL-Funktionen neu deklarieren muss :D |
Der Compiler mekert über das FPortHandle: "Undefinierter Bezeichner...
|
Code:
FPortHandle: THandle;
|
DANKE :D
|
Das ist auch nicht der komplette Code, den ich oben gepostet habe.
Code:
unit COMPort;
interface uses Windows, SysUtils, Classes; type TComPortNumber = (ComNone, Com1, Com2, Com3, Com4, Com5, Com6, Com7); // ggf. erweitern TComPort = class(TObject) private FPort: TComPortNumber; FPortHandle: THandle; Fdcb: TDCB; FRaiseOpenException: Boolean; procedure SetPort(Value: TComPortNumber); procedure SetDCB(const Value: TDCB); protected function GetHandle: THandle; virtual; procedure ClosePort; virtual; public constructor Create; destructor Destroy; override; function Write(const buf; size: Cardinal): Cardinal; function Read(var buf; size: Cardinal): Cardinal; function ClearAll: Boolean; // clears the output and input buffer function ClearInput: Boolean; // clears the input buffer function ClearOutput: Boolean; // clears the output buffer property Port: TComPortNumber read FPort write SetPort; property DCB: TDCB read Fdcb write SetDCB; property Handle: THandle read GetHandle; property RaiseOpenException: Boolean read FRaiseOpenException write FRaiseOpenException; end; const // TDCB.Flags fBinary = $0001; // binary mode, no EOF check fParity = $0002; fDtrControlEnable = $0010; // DTR flow control type fRtsControlEnable = $1000; // RTS flow control enable implementation constructor TComPort.Create; begin inherited; FPort := ComNone; FPortHandle := 0; FillChar(Fdcb, SizeOf(Fdcb), 0); FRaiseOpenException := False; end; destructor TComPort.Destroy; begin ClosePort; inherited; end; procedure TComPort.ClosePort; begin if FPortHandle <> 0 then begin // Port schließen CloseHandle(FPortHandle); FPortHandle := 0; end; end; function TComPort.GetHandle: THandle; var commtimeouts: TCommTimeouts; portname: String; begin case FPort of ComNone: begin ClosePort; Result := 0; end; else begin // case else if FPortHandle <> 0 then begin Result := FPortHandle; exit; end; portname := '\\.\COM' + IntToStr(Integer(FPort)); FPortHandle := CreateFile(PChar(portname), // name of COM device to open GENERIC_READ or GENERIC_WRITE, // read-write access 0, nil, // not used OPEN_EXISTING, // required for tape devices 0, 0); // not used Result := FPortHandle; if Result = INVALID_HANDLE_VALUE then Result := 0; if (FPortHandle <> 0) then begin // Device-Parameter setzen Fdcb.DCBlength := SizeOf(Fdcb); GetCommState(FPortHandle, Fdcb); Fdcb.Flags := dcb.Flags and not (fDtrControlEnable or fRtsControlEnable) or fBinary; Fdcb.BaudRate := CBR_19200; // baud Fdcb.ByteSize := 8; Fdcb.Parity := NOPARITY; Fdcb.StopBits := ONESTOPBIT; SetCommState(FPortHandle, Fdcb); // Timeout für ReadFile() setzen commtimeouts.ReadIntervalTimeout := 0; commtimeouts.ReadTotalTimeoutMultiplier := 5; commtimeouts.ReadTotalTimeoutConstant := 100; SetCommTimeouts(FPortHandle, commtimeouts); end; if (Result = 0) and (FRaiseOpenException) then RaiseLastWin32Error; end; // case else end; // case end; procedure TComPort.SetPort(Value: TComPortNumber); begin if Value = FPort then exit; FPort := Value; ClosePort; GetHandle; // Handle erzeugen end; procedure TComPort.SetDCB(const Value: TDCB); var h: THandle; begin h := Handle; if h = 0 then exit; if SetCommState(h, Value) then begin if not GetCommState(h, Fdcb) then Move(Value, Fdcb, SizeOf(Fdcb)); end; end; function TComPort.Write(const buf; size: Cardinal): Cardinal; begin Result := 0; if size = 0 then exit; if not WriteFile(Handle, buf, size, Result, nil) then Result := -1 * Result; end; function TComPort.Read(var buf; size: Cardinal): Cardinal; begin Result := 0; if size = 0 then exit; if not ReadFile(Handle, buf, size, Result, nil) then Result := -1 * Result; end; function TComPort.ClearAll: Boolean; // clears the output and input buffer begin Result := PurgeComm(Handle, PURGE_TXCLEAR or PURGE_RXCLEAR); end; function TComPort.ClearInput: Boolean; // clears the input buffer begin Result := PurgeComm(Handle, PURGE_RXCLEAR); end; function TComPort.ClearOutput: Boolean; // clears the output buffer begin Result := PurgeComm(Handle, PURGE_TXCLEAR); end; end. |
Wie steuer ich jetzt die TXD-LEitung von meinem "Virtuellen"-COM?
|
Schaue dir einmal die TDCB Struktur im PSDK an. Dort müsstest du fündig werden.
Zu setzen der TDCB Struktur:
Code:
// ComPort: TComPort;
var dcb: TDCB; begin dcb := ComPort.DCB; // deine Änderungen an der Struktur hier: dcb.BaudRate := CBR_2400; ComPort.DCB := dcb; end; |
Irgendwie bin ich immernochnicht schlauer als vorher.
Ich muss die TXD-Leitung seperat ansteuern können. Ich habe eine Anzege aus der Bochumer U-Bahn hier ligen, und die hat ein sehr merkwürdiges Protokoll: IBIS Die TXD-Leitung ist immer 1, und so weiter.... Bei meinem Alten Laptop kalppte das alte Prog. auch problemlos, nur an meinem neuen ist kein COM-PORT mehr dran, daher hab ich mir ein USB->Serial converter gekauft. Nur jetzt lässt sich dieser neue COM-PORT nicht mit meinem alten Prog. ansteuern.... MFG THOMAS |
Mein letztes Posting war falsch. Ich wusste nicht mehr genau, was TXD ist (Transmit Data). Diese Leitung kannst du über die Write() Methode ansprechen. Die RXD (Receive Data) kannst du über die Methode Read() ansprechen. Die DCB-Struktur wirst du aber dennoch benötigen, da du mit Sicherheit die baud-Rate ändern musst.
|
Ich möchte die Leitung ja ohne übergreifendes Protokoll ansteueren.
Zum Beispiel: Wenn ich ein Button klick wird die 1 wenn ich ein anderes klick wieder 0 usw... MFG Thomas |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:00 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz