![]() |
TSerial - RS232 ansprechen
Hallo Allerseits,
ich möchte für ein Mikrocontrollerprojekt eine Anwendung in Delphi (7) schreiben, welches Datenpakete seriell senden und empfangen kann. Ich habe mir die TComPort-Komponente installiert und versuche das damit.Leider ist mein Fachenglisch nicht das beste :gruebel: Aus Gründen des besseren Verstehens, erhoffe ich mir von der (deutschen) TSerial Komponente von R.Reusch mehr Erfolge als ich bisher habe. Weiß jemand woher ich noch die TSerial - Komponente bekommen kann, ohne gleich ein Zeitschriftenabbo auslösen zu müssen ??? Danke - Andrej! |
Re: TSerial - RS232 ansprechen
Hallo,
die TSerial Komponente ist lizenzpflichtig. Mit dem Erwerb der entsprechenden Toolbox Zeitschrift erhält man auch eine Lizenz. Ich habe selbst mal eine Komponente geschrieben, die Du gerne verwenden darfst. - arno
Delphi-Quellcode:
unit Com;
interface uses WinTypes, WinProcs, Classes, SysUtils; type TRTSMode = (RTS_DISABLED, RTS_ENABLED, RTS_HANDSHAKE, RTS_TOGGLE); TDTRMode = (DTR_DISABLED, DTR_ENABLED, DTR_HANDSHAKE); TParity = (NOPARITY, ODDPARITY, EVENPARITY, MARKPARITY, SPACEPARITY); TStopbits = (ONESTOPBIT, ONE5STOPBITS, TWOSTOPBITS); TCOM = class(TComponent) private FDCB: TDCB; FHandle: Cardinal; FTimeouts: TCommTimeouts; FError: Cardinal; FComNo: byte; FBaud: word; FParity: TParity; FDatabits: byte; FStopbits: TStopbits; function GetRTS: boolean; procedure SetRTS(const Value: boolean); function GetDTR: boolean; procedure SetDTR(const Value: boolean); function GetDCD: boolean; function GetDSR: boolean; function GetRI: boolean; function GetCTS: boolean; function GetIsOpen: boolean; function GetInBufUsed: cardinal; function GetOutBufUsed: cardinal; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; function TestComPortAvailable(ComNo: integer): boolean; function Open(ComNo: integer; RTSMode: TRTSMode; DTRMode: TDTRMode): boolean; function RxFlush: boolean; function TxFlush: boolean; function Send(Data: Char): boolean; overload; function Send(Data: PChar; Len: cardinal): boolean; overload; function GetChar(var data: Char): boolean; procedure Close; procedure Reset; published property ComNo: byte read FComNo; property Baud: word read FBaud write FBaud; property Databits: byte read FDatabits write FDatabits; property Stopbits: TStopbits read FStopbits write FStopbits; property Parity: TParity read FParity write FParity; property IsOpen: boolean read GetIsOpen; property InBufUsed: cardinal read GetInBufUsed; property OutBufUsed: cardinal read GetOutBufUsed; property Error: cardinal read FError; property RTS: boolean read GetRTS write SetRTS; property CTS: boolean read GetCTS; property DTR: boolean read GetDTR write SetDTR; property DSR: boolean read GetDSR; property RI: boolean read GetRI; property DCD: boolean read GetDCD; end; var FCOM: TCOM; implementation {----------------------------------------------------------------------------------------------} constructor TCOM.Create(AOwner: TComponent); begin inherited Create(AOwner); FHandle := INVALID_HANDLE_VALUE; Baud := CBR_9600; Databits := 8; Parity := NOPARITY; StopBits := ONESTOPBIT; end; {----------------------------------------------------------------------------------------------} destructor TCOM.Destroy; begin if IsOpen then Close; { Port schließen falls geöffnet } inherited destroy; end; {----------------------------------------------------------------------------------------------} function TCOM.TestComPortAvailable(ComNo: integer): boolean; begin Result := Open(ComNo, RTS_DISABLED, DTR_DISABLED); end; {----------------------------------------------------------------------------------------------} function TCOM.Open(ComNo: integer; RTSMode: TRTSMode; DTRMode: TDTRMode): boolean; var init: string; begin if FHandle = INVALID_HANDLE_VALUE then begin init := '\\.\COM' + IntToStr(ComNo); FHandle := CreateFile(@init[1], GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if FHandle <> INVALID_HANDLE_VALUE then begin FComNo := ComNo; // aktuelle Einstellungen ermitteln if GetCommState(FHandle, FDCB) then begin // rudimentäre Parameter setzen FDCB.Baudrate := FBaud; FDCB.Bytesize := Databits; FDCB.Parity := Ord(FParity); FDCB.Stopbits := Ord(FStopbits); // RTS Modus setzen FDCB.flags := FDCB.flags and $CFFB; {RTS aus} case RTSMode of RTS_ENABLED: FDCB.flags := FDCB.flags or $1000; {RTS ein} RTS_HANDSHAKE: FDCB.flags := FDCB.flags or $2004; {RTS Handshake ein (gekoppelt an RX Buffer 0= Empfangspuffer zu 3/4 voll)} RTS_TOGGLE: FDCB.flags := FDCB.flags or $3000; {RTS gekoppelt an Tx Buffer (1=Daten im Sendepuffer)} end; // DTR Modus setzen FDCB.flags := FDCB.flags and $FFC7; {DTR aus (und bleibt aus)} case DTRMode of DTR_ENABLED: FDCB.flags := FDCB.flags or $0010; {DTR ein (und bleibt ein)} DTR_HANDSHAKE: FDCB.flags := FDCB.flags or $0028; {DTR Handshake ein} end; if SetCommState(FHandle, FDCB) then begin if SetupComm(FHandle, 1024, 1024) then {Rx-/Tx-Buffer-Einstellungen} begin FTimeouts.ReadIntervalTimeout := 0; {Timeoutzeiten setzen} FTimeouts.ReadTotalTimeoutMultiplier := 0; FTimeouts.ReadTotalTimeoutConstant := 1; FTimeouts.WriteTotalTimeoutMultiplier := 0; FTimeouts.WriteTotalTimeoutConstant := 0; SetCommTimeouts(FHandle, FTimeouts); end; end; end; end; end; FError := GetLastError; if Error <> 0 then begin Close; end; Result := Error = 0; { Ergebnis zurückgeben } end; {-----------------------------------------------------------------------------------------------} function TCOM.GetCTS: boolean; var nStatus: cardinal; begin Result := false; if FHandle <> INVALID_HANDLE_VALUE then begin if GetCommModemStatus(FHandle, nStatus) then Result := (nStatus and MS_CTS_ON) > 0; end; end; {-----------------------------------------------------------------------------------------------} function TCOM.GetDSR: boolean; var nStatus: cardinal; begin Result := false; if FHandle <> INVALID_HANDLE_VALUE then begin if GetCommModemStatus(FHandle, nStatus) then Result := (nStatus and MS_DSR_ON) > 0; end; end; {-----------------------------------------------------------------------------------------------} function TCOM.GetIsOpen: boolean; begin Result := FHandle <> INVALID_HANDLE_VALUE; end; {-----------------------------------------------------------------------------------------------} function TCOM.GetInBufUsed: cardinal; var Comstat: _Comstat; Errors: DWord; begin if ClearCommError(FHandle, Errors, @Comstat) then Result := Comstat.cbInQue else Result := 0; end; {-----------------------------------------------------------------------------------------------} function TCOM.GetOutBufUsed: cardinal; var Comstat: _Comstat; Errors: DWord; begin if ClearCommError(FHandle, Errors, @Comstat) then Result := Comstat.cbOutQue else Result := 0; end; {-----------------------------------------------------------------------------------------------} function TCOM.GetRI: boolean; var nStatus: cardinal; begin Result := false; if FHandle <> INVALID_HANDLE_VALUE then begin if GetCommModemStatus(FHandle, nStatus) then Result := (nStatus and MS_RING_ON) > 0; end; end; {-----------------------------------------------------------------------------------------------} function TCOM.GetRTS: boolean; begin Result := false; if GetCommState(FHandle, FDCB) then begin Result := (FDCB.Flags and $3000) > 0; end; end; {-----------------------------------------------------------------------------------------------} procedure TCOM.SetRTS(const Value: boolean); begin if (Value = True) then EscapeCommFunction(FHandle, WinTypes.SETRTS) else EscapeCommFunction(FHandle, WinTypes.CLRRTS); end; {-----------------------------------------------------------------------------------------------} function TCOM.GetDTR: boolean; begin Result := false; if GetCommState(FHandle, FDCB) then begin Result := (FDCB.Flags and $0010) > 0; end; end; {-----------------------------------------------------------------------------------------------} procedure TCOM.SetDTR(const Value: boolean); begin if (Value = True) then EscapeCommFunction(FHandle, WinTypes.SETDTR) else EscapeCommFunction(FHandle, WinTypes.CLRDTR); end; {-----------------------------------------------------------------------------------------------} function TCOM.GetDCD: boolean; var nStatus: cardinal; begin Result := false; if FHandle <> INVALID_HANDLE_VALUE then begin if GetCommModemStatus(FHandle, nStatus) then Result := (nStatus and MS_RLSD_ON) > 0; end; end; {-----------------------------------------------------------------------------------------------} procedure TCOM.Close; begin if CloseHandle(FHandle) then { Schnittstelle schließen } FHandle := INVALID_HANDLE_VALUE; FError := GetLastError; end; {-----------------------------------------------------------------------------------------------} procedure TCOM.Reset; begin if not EscapeCommFunction(FHandle, WinTypes.RESETDEV) then FError := GetLastError; end; {-----------------------------------------------------------------------------------------------} function TCOM.RxFlush: boolean; begin if FHandle <> INVALID_HANDLE_VALUE then begin PurgeComm(FHandle, PURGE_RXCLEAR); FError := GetLastError; end; Result := FError = 0; end; {-----------------------------------------------------------------------------------------------} function TCOM.TxFlush: boolean; begin if FHandle <> INVALID_HANDLE_VALUE then begin PurgeComm(FHandle, PURGE_TXCLEAR); FError := GetLastError; end; Result := FError = 0; end; {-----------------------------------------------------------------------------------------------} function TCOM.Send(Data: Char): boolean; var nWritten, nCount: Cardinal; begin Result := false; if FHandle <> INVALID_HANDLE_VALUE then begin nCount := SizeOf(Data); if WriteFile(FHandle, Data, nCount, nWritten, nil) then begin Result := nCount = nWritten; end; FError := GetLastError; end; end; {-----------------------------------------------------------------------------------------------} function TCOM.Send(Data: PChar; Len: cardinal): boolean; var nWritten, nCount: Cardinal; begin Result := false; if FHandle <> INVALID_HANDLE_VALUE then begin nCount := Len; if WriteFile(FHandle, Data^, nCount, nWritten, nil) then begin Result := nCount = nWritten; end; FError := GetLastError; end; end; {-----------------------------------------------------------------------------------------------} function TCOM.GetChar(var data: Char): boolean; var nCount, nRead: cardinal; begin Result := false; if FHandle <> INVALID_HANDLE_VALUE then begin nCount := SizeOf(data); if InBufUsed >= nCount then begin if ReadFile(FHandle, data, nCount, nRead, nil) then begin Result := nCount = nRead; end; end; FError := GetLastError; end; end; end. |
Re: TSerial - RS232 ansprechen
Hi Arno,
danke für deine Antwort - ich werde umgehend mal deine Komponente ausprobieren. :thumb: Wenn ich Fragen habe darf ich mich doch melden :coder: Grüße - Andrej! |
Re: TSerial - RS232 ansprechen
Sehr übersichtlich, sehr benutzerfreundlich, einfach TOP!
:hello: :spin: :thumb: :bounce1: :bouncing4: :bounce2: :dancer2: :dancer: wirklich tolle Unit! einfach einbinden, geht, hab ich vorher noch NIE gehabt! Perfekt, ich freue mich! LG Superwinger Edit: Zitat:
|
Re: TSerial - RS232 ansprechen
Guten Tag,
ich (Neuling/ahnungslos)bin im Zuge eines Schulprojekts auf dieses Forum und diesen Thread gestoßen. Auch bei uns ein Mikrocontrollerprojekt. Unser Problem ist im Wesentlichen, den Quelltext von arnold mueller zu verstehen (einsetzen ist kein Problem- aber man muss ja auch verstehen was passiert). Unser Kernproblem hierbei ist die TCOM.Send Funktion. Wenns nicht zuviel verlangt wäre, würde es uns sehr weiterhelfen, wenn jemand versuchen würde, den Quelltext etwas zu erläutern und zu kommentieren, damit wir effektiv mit der Komponente arbeiten können. Und wenns geht, dabei berücksichtigen, das wir auf dem Stand Stufe 13.1 sind- wenig Fachchinesisch und viel "Zeile xy hängt zusammen mit Zeile z und löst dieses und jenes aus" Vielen Dank im Voraus, falls sich jemand die Mühe macht- ein paar armen, verzweifelten Schülern könnte damit sehr geholfen werden! -LuJ- :glaskugel: |
Re: TSerial - RS232 ansprechen
Moin!
Zitat:
Gruß, Jens |
Re: TSerial - RS232 ansprechen
Zitat:
Delphi-Quellcode:
HTHfunction TCOM.Send(Data: Char): boolean; var nWritten, nCount: Cardinal; begin Result := false; // Initialisierung if FHandle <> INVALID_HANDLE_VALUE then // Wenn der Comport aktiviert ist und daher benutzt werden kann begin nCount := SizeOf(Data); // Zählvariable auf die Größe der zu übertragenden Daten setzen // FHandle = Handle des Comports, Data = zu sendende Daten, nCount = Größe von Data // nWritten = gesendete Anzahl an Daten. Diese Variable wird von WriteFile gefüllt if WriteFile(FHandle, Data, nCount, nWritten, nil) then // und Daten abschicken. begin Result := nCount = nWritten; // Wenn alle Daten übertragen wurden ist die Funktion erfolgreich end; FError := GetLastError; end; end; |
Re: TSerial - RS232 ansprechen
Zitat:
Beim Verständnis an und für sich hakts nicht, mit dem Prinzip kommt man noch klar. Bei der Aufschlüsselung des Quelltextes hakts dann aber- deshalb auch vielen Dank an angos für die Mühe! Ich denke das bringt uns ein Stückchen weiter :) Edit: Wenn man voraussetzt, dass an der seriellen Schnittstelle nichts dranhängt (Nullmodemkabel zB), würde das Programm dann immer bei " FHandle = INVALID_HANDLE_VALUE " den Geist aufgeben? Oder anders formuliert, wenn an der seriellen Schnittstelle keine "Verbindung" hängt, welche Reaktion des Programms würdet ihr erwarten? |
Re: TSerial - RS232 ansprechen
Es gibt keine Möglichkeit herauszufinden ob etwas an der Schnittstelle hängt, die daten werden dann also einfach ins nirvana gesendet.
|
Re: TSerial - RS232 ansprechen
Zitat:
Grundlagen gibt es hier: ![]() - arno |
Re: TSerial - RS232 ansprechen
Zitat:
Mist... dann machen wirs wohl nach wie vor falsch. An diesem Punkt: "FHandle = INVALID_HANDLE_VALUE" hängt sich unser Programm jedes Mal auf. Hätte jemand vielleicht ein kleines Anwendungsbeispiel für das Ausführen von arnold muellers Quelltext? Also was ganz simples, bspw. die Ausgabe eines Buchstaben über die serielle Schnittstelle- einfach ins Nirvana hinein, ohne jeden Sinn, einfach als Beispiel. |
Re: TSerial - RS232 ansprechen
Das Beispiel sendet ein Hallo Welt über COM1 und wartet 1 Sekunde auf Antwort.
Delphi-Quellcode:
-procedure TForm1.ButtonClick(Sender: TObject); var c: Char; tx_buffer, rx_buffer: string; tick: cardinal; begin tx_buffer := 'Hallo Welt!'; with TCom.Create(nil) do try // com 1 öffnen if Open(1,RTS_DISABLED,DTR_DISABLED) then begin // senden if Send(PChar(tx_buffer),Length(tx_buffer))then begin tick := GetTickCount; // 1 Sekunde auf Daten warten repeat // Daten aus der Schnittstelle lesen, sofern vorhanden if GetChar(c) then begin rx_buffer := rx_buffer + c; end; until (GetTickCount-Tick) > 1000; end; end; finally // com 1 schließen Close; Free; end; end; arno |
Re: TSerial - RS232 ansprechen
Danke, wunderbar!
Das Beispiel hilft uns schonmal extrem viel weiter, wir habens jetzt soweit, das unsere Kommunikation einseitig funktioniert- also setzen wir uns ans Nächste... ...d.h. ich melde mich sicher bald nochmal mit weiteren Fragen ;9 Danke schonmal für eure bisherige Geduld! |
Re: TSerial - RS232 ansprechen
Hallo,
ich mache auch gerade was mit Microcontrollern und habe die unit oben auch mal ausprobiert. Sie funktioniert mit dem Beispielcode von arnold mueller auch sehr gut. Jetzt möchte ich aber nicht, wie im Beispiel, 1 Sekunde auf Daten warten, sondern dauerhaft auslesen um dann z.b. bei bestimmten gesendeten zeichen einzelne daten aus dem datenstrom entnehmen. Hat da jemd eine Idee, ob/wie sich das bewerkstelligen ließe? Gruß zebrafalke |
Re: TSerial - RS232 ansprechen
Hallo zebrafalke,
es gibt noch bei Sourceforge die Komponente Async Professional mit der man eigentlich sehr gut die Serielle Schnittstelle auslesen kann. Dort sind unter anderem auch Demos mit dabei. Du hast jetzt nicht genau geschrieben welche Daten (in welcher Form) die Daten anfallen. Aber ich postuliere mal, dass das mit dieser Komponente gehen müsste. ![]() Bis bald Chemiker |
Re: TSerial - RS232 ansprechen
´Hallo!
hab mal ne frage und zwar is da ne funktion dabei, die mir sagt ob an irgeneinem pin ein signal anliegt? |
Re: TSerial - RS232 ansprechen
Hallo Chriss112,
in Post #15 steht der Link zum Downloaden der Komponente, dabei ist auch eine sehr ausführliche Hilfe. Man kann bestimmte Zustände mit einem "TriggerStatus" anzeigen lassen. Bis bald Chemiker |
Re: TSerial - RS232 ansprechen
Vielen Dank!
|
Re: TSerial - RS232 ansprechen
Dann hätte ich doch auch mal eine Frage.
Ich möchte eine dauerhafte Spannung an einem Pin anliegen haben, mein Code sieht bis jetzt so aus:
Delphi-Quellcode:
Das Zeichen 'ÿ' habe ich genommen, weil es als Byte dargestellt "1111 1111" ist und daher dauernd Spannung anliegen müsste. Ich weiß zwar nicht ob mein Gedankengang bis jetzt richtig ist, doch ich weiß nicht an welchem Pin das Signal ausgegeben wird. Kann man das auch einstellen oder wird es auf allen Pins ausgegeben?
procedure TForm1.Button1Click(Sender: TObject);
var Zeichen : char; begin if Button1.Caption = 'Start' then begin Button1.Caption := 'Stop'; Zeichen := 'ÿ'; with TCom.Create(nil) do try Label2.Caption := 'läuft'; Label2.Font.Color := clLime; if Open(1,RTS_DISABLED,DTR_DISABLED) then while Button1.Caption = 'Stop' do begin Send(Zeichen); Application.ProcessMessages; end; finally Label2.Caption := 'gestoppt'; Label2.Font.Color := clRed; Button1.Caption := 'Start'; Close; Free; end; end else Button1.Caption := 'Start'; end; Hinzufügen möchte ich, dass ich ein altes Kabel einer Maus angeschlossen habe und dieses aufgeschnitten habe.Diese Kabel hat aber nur 5 Adern, kann ich damit überhaupt arbeiten? Edit: Zitat:
|
Re: TSerial - RS232 ansprechen
|
Re: TSerial - RS232 ansprechen
Ok, es funktioniert jetzt einigermaßen. Schließe ich eine LED zwischen Pin 3 (Sendedaten) und Pin 5 (Ground) so leuchtet die LED wenn ich meine Funktion anschalte und wenn ich sie wieder deaktiviere, dann leuchtet die LED nicht mehr. Schließe ich die LED jedoch verkehrt herum an, dann leuchtet sie immer, auch wenn kein Signal gegeben werden sollte.
Ich werde noch irgendwann ausprobieren, ob man verschiedene Signale geben kann, denn bei einem 0-Bit wird anscheinend eine positive Spannung abgegeben und bei einem 1-Bit eine negative Spannung. Vielleicht wird das aber auch von Stopbits und anderen Bits die mitgesendet werden überdeckt. |
Re: TSerial - RS232 ansprechen
Zitat:
logische Null auf +12V. Du solltest aber vorsichtig damit sein, Verbraucher direkt an die Schnittstelle anszuschließen. Du solltest zumindest eine galvanische Trennung haben - das ist in manchen Fälllen für den PC überlebenswichtig. Grüße Klaus |
Re: TSerial - RS232 ansprechen
Wann kann dies gefährlich werden, wenn Kurzschlüsse entstehen, oder wenn zu viel Spannung auf den PC kommt? Würde ein MOSFET oder ein Transistor dazu ausreichen? Diese schalten ja nur wenn negative Spannung richtig anliegt, so sollte man dann auch richtig Ströme schalten können.
Was ich jedoch schade finde, ist dass man nur eine Leitung schalten kann. Ich werde mich mal auf Conrad umsehen, ob ich nicht irgendeine Platine mit USB Interface finde, die mehr kann. Vielleicht kennt jemand von euch auch eine gute. |
Re: TSerial - RS232 ansprechen
Zitat:
Probleme könnten hier eher entstehen, wenn zu große Ströme direkt an den Schnittstellen hängen. Eine galvanische Trennung wäre als spontane Idee wohl mit Optokopplern zu erreichen, aber bis jetzt hab ich eigentlich (am LPT) auch MOSFET benutzt. |
Re: TSerial - RS232 ansprechen
Hallihallo,
Ich habe auch vor mit einem Mikrocontroller zu komunizieren. Im HyperTerminal funktioniert das bereits. Das läuft in etwa so: Ich sende ein beliebiges Zeichen und der Controller antwortet mit 8 Bytes. Wie gesagt im HT läuft es wunderbar, aber mein Programm will noch nicht so richtig. Folgenden Code nutze ich: (abgeändert vom Beispielcode weiter vorn)
Delphi-Quellcode:
Die Variable COM wird in den Einstellungen gesetzt.
procedure TForm1.readcomClick(Sender: TObject);
var c: Char; digits: array [0..7] of string; tick: cardinal; count: Integer; begin c := 'x'; // zu sendendes Zeichen with TCom.Create(nil) do try // com öffnen if Open(COM,RTS_DISABLED,DTR_DISABLED) then begin // senden if Send(c) then //Zeichen senden begin tick := GetTickCount; count := 0; // 1 Sekunde bzw. auf 8 Bytes Daten warten repeat // Daten aus der Schnittstelle lesen, sofern vorhanden if GetChar(c) then begin digits[count] := c; count := count+1; end; until ((GetTickCount-Tick) > 1000) or (count >= 7); if count >= 7 then //Die erhaltenen Zeichen verarbeiten begin time1.Text := digits[0] + digits[1] + ',' + digits[2] + digits[3]; time2.Text := digits[4] + digits[5] + ',' + digits[6] + digits[7]; end; end; end; finally // com schließen Close; Free; end; end; Beim HT hab ich folgendes eingestellt: 9600Baud; keine Parität; 1Stopbit; Datenbits: 8; Keine Flussteuerung Ich hoffe ihr findet meinen Denkfehler. |
Re: TSerial - RS232 ansprechen
Hallo,
was funktioniert denn nicht? Bist Du schon einmal in der Routine einen Haltepunkt gesetzt und bist mit F8 den Code schrittweise durchgegangen? Grüße Klaus |
Re: TSerial - RS232 ansprechen
Es erzeugt ja keinen Fehler, deshalb bin ich ja auch total überfragt was grade los ist.
|
Re: TSerial - RS232 ansprechen
Zitat:
Dann setze mal einen Haltepunkt und arbeite mit F8 den Code ab. Dann wirst Du sehen, ob alles so läuft wie Du es Dir vorgestellt hast. Grüße Klaus |
Re: TSerial - RS232 ansprechen
Wie gesagt, es sollte ein Zeichen gesendet werden. Dann soll die Antwort von 8 Zeichen empfangen werden. Ob das senden funktioniert kann ich nicht sagen weil ich nicht weiß wie ichs testen soll. Empfangen tut er jedenfalls nix.
Gruß Lee |
Re: TSerial - RS232 ansprechen
Zuerstmal musst Du eingrenzen wo das Problem überhaupt liegt. Welcher Microcontroller? Je nach Plattform gibts mehr oder weniger erschwingliche Hardwaredebugger dafür. Zweitens solltest Du beim Microcontroller erstmal ein paar simple Signalisierungsmöglichkeiten schaffen. Immer wieder gern genommen ist z.B. eine LED die angeht, wenn der Controller ein Zeichen empfangen hat. So kann man Schritt für Schritt einkreisen, was denn überhaupt das Problem ist. Hast Du z.B. daran gedacht RX und TX zu kreuzen? Senden auf der einen ist ja Empfangen auf der anderen Seite.
|
Re: TSerial - RS232 ansprechen
Also ich habe mir jetz ne LED an einen ausgang gebastelt. Wenn ich per Delphi sende passiert gar nix. Mach ichs per HyperTerminal geht sie an sobald ich was sende.
Zitat:
Gruß Lee |
Re: TSerial - RS232 ansprechen
Wenn Du nicht ganz grobe Verdrahtungsfehler drin hast (wovon ich nicht ausgehe) dann zeigt das ja zumindest schonmal, dass das Senden an den Controller geht, wenn auch nicht mit Delphi :mrgreen:. Geht denn auch die Antwort des Controllers? Die sollte durchaus auch per Hyperterminal zu sehen sein. Wenn das klappt, sind wir schonmal einen Schritt weiter mit der Fehlereingrenzung. Wenn der Part des Controllers dann komplett funktioniert, dann sehen wir uns die Delphi-Seite an. Immer einen Schritt nach dem anderen machen.
|
Re: TSerial - RS232 ansprechen
Ja der Hardware Teil funktioniert. Wenn ich per HyperTerminal ein 'x' sende, antwortet mir der Controller mit '12345678'.
Wenn ich per HT sende geht die LED auch an, da der Controller ein Zeichen empfangen hat. Bei Delphi ist dies nicht der fall. Also vermute ich mal, sendet Delphi gar nicht, oder so, dass der Controller es nicht lesen kann. Gruß Lee |
Re: TSerial - RS232 ansprechen
Hast du schon mit
![]() |
Re: TSerial - RS232 ansprechen
Per HT sagt mir Portmon folgendes:
Delphi-Quellcode:
per Delphi macht es das:
0.12418143 hypertrm.exe IRP_MJ_CREATE Serial2 SUCCESS Options: Open
0.00000782 hypertrm.exe IOCTL_SERIAL_SET_QUEUE_SIZE Serial2 SUCCESS InSize: 8192 OutSize: 8192 0.00000251 hypertrm.exe IOCTL_SERIAL_CONFIG_SIZE Serial2 SUCCESS Size: 0 0.00000196 hypertrm.exe IOCTL_SERIAL_GET_BAUD_RATE Serial2 SUCCESS 0.00000196 hypertrm.exe IOCTL_SERIAL_GET_LINE_CONTROL Serial2 SUCCESS 0.00000196 hypertrm.exe IOCTL_SERIAL_GET_CHARS Serial2 SUCCESS 0.00000196 hypertrm.exe IOCTL_SERIAL_GET_HANDFLOW Serial2 SUCCESS 0.00000196 hypertrm.exe IOCTL_SERIAL_GET_BAUD_RATE Serial2 SUCCESS 0.00000196 hypertrm.exe IOCTL_SERIAL_GET_LINE_CONTROL Serial2 SUCCESS 0.00000196 hypertrm.exe IOCTL_SERIAL_GET_CHARS Serial2 SUCCESS 0.00000196 hypertrm.exe IOCTL_SERIAL_GET_HANDFLOW Serial2 SUCCESS 0.00000223 hypertrm.exe IOCTL_SERIAL_SET_BAUD_RATE Serial2 SUCCESS Rate: 9600 0.00275426 hypertrm.exe IOCTL_SERIAL_SET_RTS Serial2 SUCCESS 0.00297496 hypertrm.exe IOCTL_SERIAL_SET_DTR Serial2 SUCCESS 0.00000279 hypertrm.exe IOCTL_SERIAL_SET_LINE_CONTROL Serial2 SUCCESS StopBits: 1 Parity: NONE WordLength: 8 0.00295652 hypertrm.exe IOCTL_SERIAL_SET_CHAR Serial2 SUCCESS EOF:0 ERR:0 BRK:0 EVT:0 XON:11 XOFF:13 0.01298852 hypertrm.exe IOCTL_SERIAL_SET_HANDFLOW Serial2 SUCCESS Shake:80000001 Replace:80000040 XonLimit:80 XoffLimit:200 0.00000391 hypertrm.exe IOCTL_SERIAL_SET_TIMEOUTS Serial2 SUCCESS RI:10 RM:0 RC:0 WM:0 WC:5000 0.00000363 hypertrm.exe IOCTL_SERIAL_SET_WAIT_MASK Serial2 SUCCESS Mask: RLSD ERR 0.00000000 hypertrm.exe IOCTL_SERIAL_WAIT_ON_MASK Serial2 0.00000000 hypertrm.exe IRP_MJ_READ Serial2 Length 80 0.00076993 hypertrm.exe IRP_MJ_WRITE Serial2 SUCCESS Length 1: . 0.00000670 hypertrm.exe IOCTL_SERIAL_GET_COMMSTATUS Serial2 SUCCESS 0.00092945 hypertrm.exe IRP_MJ_WRITE Serial2 SUCCESS Length 1: . 21.23459630 hypertrm.exe IRP_MJ_READ Serial2 TIMEOUT Length 8: 12305678
Delphi-Quellcode:
Gruß Lee
0.12224207 Zeitmessung.exe IRP_MJ_CREATE Serial2 SUCCESS Options: Open
0.00000475 Zeitmessung.exe IOCTL_SERIAL_GET_BAUD_RATE Serial2 SUCCESS 0.00000251 Zeitmessung.exe IOCTL_SERIAL_GET_LINE_CONTROL Serial2 SUCCESS 0.00000223 Zeitmessung.exe IOCTL_SERIAL_GET_CHARS Serial2 SUCCESS 0.00000223 Zeitmessung.exe IOCTL_SERIAL_GET_HANDFLOW Serial2 SUCCESS 0.00000196 Zeitmessung.exe IOCTL_SERIAL_GET_BAUD_RATE Serial2 SUCCESS 0.00000196 Zeitmessung.exe IOCTL_SERIAL_GET_LINE_CONTROL Serial2 SUCCESS 0.00000196 Zeitmessung.exe IOCTL_SERIAL_GET_CHARS Serial2 SUCCESS 0.00000196 Zeitmessung.exe IOCTL_SERIAL_GET_HANDFLOW Serial2 SUCCESS 0.00000196 Zeitmessung.exe IOCTL_SERIAL_SET_BAUD_RATE Serial2 SUCCESS Rate: 9600 0.00277857 Zeitmessung.exe IOCTL_SERIAL_CLR_RTS Serial2 SUCCESS 0.00299871 Zeitmessung.exe IOCTL_SERIAL_CLR_DTR Serial2 SUCCESS 0.00000251 Zeitmessung.exe IOCTL_SERIAL_SET_LINE_CONTROL Serial2 SUCCESS StopBits: 1 Parity: NONE WordLength: 8 0.00295764 Zeitmessung.exe IOCTL_SERIAL_SET_CHAR Serial2 SUCCESS EOF:0 ERR:0 BRK:0 EVT:0 XON:11 XOFF:13 0.00000307 Zeitmessung.exe IOCTL_SERIAL_SET_HANDFLOW Serial2 SUCCESS Shake:80000000 Replace:80000000 XonLimit:2048 XoffLimit:512 0.00000223 Zeitmessung.exe IOCTL_SERIAL_SET_QUEUE_SIZE Serial2 SUCCESS InSize: 1024 OutSize: 1024 0.00000223 Zeitmessung.exe IOCTL_SERIAL_SET_TIMEOUTS Serial2 SUCCESS RI:0 RM:0 RC:1 WM:0 WC:0 0.00090235 Zeitmessung.exe IRP_MJ_WRITE Serial2 SUCCESS Length 1: x 0.00000279 Zeitmessung.exe IOCTL_SERIAL_GET_COMMSTATUS Serial2 SUCCESS 0.00000223 Zeitmessung.exe IOCTL_SERIAL_GET_COMMSTATUS Serial2 SUCCESS 0.00000223 Zeitmessung.exe IOCTL_SERIAL_GET_COMMSTATUS Serial2 SUCCESS 0.00000251 Zeitmessung.exe IOCTL_SERIAL_GET_COMMSTATUS Serial2 SUCCESS 0.00000223 Zeitmessung.exe IOCTL_SERIAL_GET_COMMSTATUS Serial2 SUCCESS 0.00000251 Zeitmessung.exe IOCTL_SERIAL_GET_COMMSTATUS Serial2 SUCCESS 0.00000223 Zeitmessung.exe IOCTL_SERIAL_GET_COMMSTATUS Serial2 SUCCESS ... es folgt noch mehr davon |
Re: TSerial - RS232 ansprechen
.. in Deinem 2. Protokoll taucht doch ein x auf
Zitat:
Grüße Klaus |
Re: TSerial - RS232 ansprechen
Das hat ja nix zu sagen, weil es das Zeichen ist was gesendet wird. Der Controller sendet aber auch zurück wenn er ein x bekommt, da er sendet sobald ein Zeichen kommt, egal welches.
Gruß Lee //EDIT: Habe jetzt herausgefunden warum es nicht ging. Mein Controller erwartete einen Zeilenumbruch bzw. ein Zeilenende oder sowas. Ohne dieses Ende antwortet er nicht, weil er glaubt nichts empfangen zu haben. Jetzt, mit Zeilenumbruch, funktioniert es wunderbar. |
AW: TSerial - RS232 ansprechen
Hallo erstmal,
vielen Dank für die Com Unit! Hab allerdings ein Problem: Ich mochte den Port RTS auf High schalten. So hab ich mir das vorgestellt
Delphi-Quellcode:
//////////////////////////////////////////////////////////////////////////////////////
procedure TForm1.Button1Click(Sender: TObject); begin with TCom.Create(nil) do try // com öffnen if Open(COM,RTS_DISABLED,DTR_DISABLED) then begin Memo1.Lines.Add ('Com'+IntToStr(Com)+' ausgewählt!'); SetRTS(akt); end; finally // com schließen Close; Free; end; /////////////////////////////////////////////////////////////////// Bei der Prozedur SetRTS gibt Delphi mir allerdings die Fehlermeldung "Missing Operator" aus. Die Variable akt(boolean) habe ich zuvor jedoch schon true zugewiesen... Kann mir jemand helfen??? Vielen Dank für eure Mühen |
AW: TSerial - RS232 ansprechen
Schmeiß erst einmal das "with" raus. Und dann scheint da noch das "end" zum "finally" zu fehlen.
|
AW: TSerial - RS232 ansprechen
Ohne with gehts gar nicht. Sorry end war noch drin-->habs lediglich nicht mitkopiert...
Denke das Problem liegt an der Prozedur:
Delphi-Quellcode:
Um diese auszuführen bzw. RTS zu schalten sollte ich sie doch lediglich so:
procedure TCOM.SetRTS(const Value: boolean);
begin if (Value = True) then EscapeCommFunction(FHandle, WinTypes.SETRTS) else EscapeCommFunction(FHandle, WinTypes.CLRRTS); end;
Delphi-Quellcode:
ausführen können oder nicht?
SetRTS(true);
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:24 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