improve structure of serial thread
This commit is contained in:
+12
-1
@@ -62,7 +62,7 @@
|
||||
<Version Value="11"/>
|
||||
<PathDelim Value="\"/>
|
||||
<Target>
|
||||
<Filename Value="CommunicationTester"/>
|
||||
<Filename Value="CommunicationTester-release"/>
|
||||
</Target>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||
@@ -98,6 +98,9 @@
|
||||
<FormatVersion Value="2"/>
|
||||
</RunParams>
|
||||
<RequiredPackages>
|
||||
<Item>
|
||||
<PackageName Value="RunTimeTypeInfoControls"/>
|
||||
</Item>
|
||||
<Item>
|
||||
<PackageName Value="LazControls"/>
|
||||
</Item>
|
||||
@@ -133,6 +136,14 @@
|
||||
<ResourceBaseClass Value="Frame"/>
|
||||
<UnitName Value="SerialPortFrameUnit"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="tcpframeunit.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<ComponentName Value="Frame1"/>
|
||||
<HasResources Value="True"/>
|
||||
<ResourceBaseClass Value="Frame"/>
|
||||
<UnitName Value="TCPFrameUnit"/>
|
||||
</Unit>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
|
||||
@@ -9,15 +9,15 @@ uses
|
||||
athreads,
|
||||
{$ENDIF}
|
||||
Interfaces, // this includes the LCL widgetset
|
||||
Forms, lazcontrols,
|
||||
Forms, lazcontrols, runtimetypeinfocontrols,
|
||||
mainunit,
|
||||
SerialManager, SerialPortFrameUnit { you can add units after this };
|
||||
SerialManager, SerialPortFrameUnit,
|
||||
TCPFrameUnit { you can add units after this };
|
||||
|
||||
{$R *.res}
|
||||
|
||||
begin
|
||||
RequireDerivedFormResource := True;
|
||||
Application.Title:='CommunicationTester';
|
||||
Application.Scaled:=True;
|
||||
Application.Initialize;
|
||||
Application.CreateForm(TMainForm, MainForm);
|
||||
|
||||
+2
-2
@@ -22,7 +22,7 @@ object MainForm: TMainForm
|
||||
Height = 580
|
||||
Top = 10
|
||||
Width = 940
|
||||
ActivePage = SerialTabSheet
|
||||
ActivePage = TabSheet2
|
||||
Anchors = [akTop, akLeft, akRight, akBottom]
|
||||
BorderSpacing.Left = 10
|
||||
BorderSpacing.Top = 10
|
||||
@@ -34,7 +34,7 @@ object MainForm: TMainForm
|
||||
Font.Pitch = fpVariable
|
||||
Font.Quality = fqDraft
|
||||
ParentFont = False
|
||||
TabIndex = 0
|
||||
TabIndex = 1
|
||||
TabOrder = 0
|
||||
object SerialTabSheet: TTabSheet
|
||||
Caption = '串口'
|
||||
|
||||
+2
-3
@@ -6,7 +6,8 @@ interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls,
|
||||
ComCtrls, Spin, SpinEx, Synaser, SerialManager, Types, SerialPortFrameUnit;
|
||||
ComCtrls, Spin, MaskEdit, SpinEx, Synaser, SerialManager, Types,
|
||||
SerialPortFrameUnit, TCPFrameUnit;
|
||||
|
||||
type
|
||||
|
||||
@@ -49,6 +50,4 @@ implementation
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
end.
|
||||
|
||||
+100
-5
@@ -5,10 +5,13 @@ unit SerialManager;
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, Synaser;
|
||||
Classes, SysUtils, Synaser;
|
||||
|
||||
type
|
||||
TRecvDataEvent = procedure(Data: string) of object;
|
||||
TConnectedEvent = procedure of object;
|
||||
TConnectedFailedEvent = procedure of object;
|
||||
TClosedEvent = procedure of object;
|
||||
|
||||
{ SerialThread }
|
||||
|
||||
@@ -16,30 +19,98 @@ type
|
||||
protected
|
||||
procedure Execute; override;
|
||||
procedure ProcessRecvEvent;
|
||||
procedure ProcessConnectedEvent;
|
||||
procedure ProcessConnectedFailedEvent;
|
||||
procedure ProcessOnCloseEvent;
|
||||
private
|
||||
MserialPort: TBlockSerial;
|
||||
MSerialName: string;
|
||||
FOnRecvData: TRecvDataEvent;
|
||||
FOnConnected: TConnectedEvent;
|
||||
FOnClosed: TClosedEvent;
|
||||
FOnConnectedFailed: TConnectedFailedEvent;
|
||||
currentRecvData: string;
|
||||
|
||||
public
|
||||
constructor Create(CreateSuspended: boolean; serialPort: TBlockSerial);
|
||||
property OnRecvData: TRecvDataEvent read FOnRecvData write FOnRecvData;
|
||||
constructor Create(CreateSuspended: boolean; serialName: string);
|
||||
destructor Destroy; override;
|
||||
|
||||
procedure Close();
|
||||
procedure SendString(Data: ansistring);
|
||||
function SendBuffer(buffer: pointer; length: integer): integer;
|
||||
procedure ConfigureSerial(baud, bits: integer; parity: char;
|
||||
stop: integer; softflow, hardflow: boolean);
|
||||
|
||||
property OnRecvData: TRecvDataEvent read FOnRecvData write FOnRecvData;
|
||||
property OnConnected: TConnectedEvent read FOnConnected write FOnConnected;
|
||||
property OnConnectedFailed: TConnectedFailedEvent
|
||||
read FOnConnectedFailed write FOnConnectedFailed;
|
||||
property OnClosed: TClosedEvent read FOnClosed write FOnClosed;
|
||||
|
||||
function isConnected(): boolean;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
constructor SerialThread.Create(CreateSuspended: boolean; serialPort: TBlockSerial);
|
||||
constructor SerialThread.Create(CreateSuspended: boolean; serialName: string);
|
||||
begin
|
||||
inherited Create(CreateSuspended);
|
||||
FreeOnTerminate := True;
|
||||
Self.MserialPort := serialPort;
|
||||
self.MSerialName := serialName;
|
||||
Self.MserialPort := TBlockSerial.Create;
|
||||
|
||||
end;
|
||||
|
||||
destructor SerialThread.Destroy;
|
||||
begin
|
||||
inherited Destroy;
|
||||
FreeAndNil(MserialPort);
|
||||
end;
|
||||
|
||||
procedure SerialThread.Close;
|
||||
begin
|
||||
MserialPort.Purge();
|
||||
MserialPort.CloseSocket();
|
||||
Terminate();
|
||||
FreeAndNil(MserialPort);
|
||||
ProcessOnCloseEvent();
|
||||
end;
|
||||
|
||||
procedure SerialThread.SendString(Data: ansistring);
|
||||
begin
|
||||
MserialPort.SendString(Data);
|
||||
end;
|
||||
|
||||
function SerialThread.SendBuffer(buffer: pointer; length: integer): integer;
|
||||
begin
|
||||
Result := MserialPort.SendBuffer(buffer, length);
|
||||
end;
|
||||
|
||||
procedure SerialThread.ConfigureSerial(baud, bits: integer; parity: char;
|
||||
stop: integer; softflow, hardflow: boolean);
|
||||
begin
|
||||
MserialPort.Config(baud, bits, parity, stop,
|
||||
softflow, hardflow);
|
||||
end;
|
||||
|
||||
function SerialThread.isConnected(): boolean;
|
||||
begin
|
||||
Result := ((MserialPort <> nil) and MserialPort.InstanceActive);
|
||||
end;
|
||||
|
||||
procedure SerialThread.Execute;
|
||||
|
||||
begin
|
||||
MserialPort.Connect(MSerialName);
|
||||
if isConnected() then
|
||||
begin
|
||||
Synchronize(@ProcessConnectedEvent);
|
||||
end
|
||||
else
|
||||
begin
|
||||
Synchronize(@ProcessConnectedFailedEvent);
|
||||
Exit;
|
||||
end;
|
||||
while not (Terminated) do
|
||||
begin
|
||||
currentRecvData := MserialPort.RecvPacket(-1);
|
||||
@@ -55,4 +126,28 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure SerialThread.ProcessConnectedEvent;
|
||||
begin
|
||||
if Assigned(FOnConnected) then
|
||||
begin
|
||||
FOnConnected();
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure SerialThread.ProcessConnectedFailedEvent;
|
||||
begin
|
||||
if Assigned(FOnConnectedFailed) then
|
||||
begin
|
||||
FOnConnectedFailed();
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure SerialThread.ProcessOnCloseEvent;
|
||||
begin
|
||||
if Assigned(FOnClosed) then
|
||||
begin
|
||||
FOnClosed();
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
+45
-54
@@ -12,6 +12,8 @@ type
|
||||
|
||||
{ TMainForm }
|
||||
|
||||
{ SerialPortFrame }
|
||||
|
||||
SerialPortFrame = class(TFrame)
|
||||
baudrateComboBox: TComboBox;
|
||||
TimerCheckBox: TCheckBox;
|
||||
@@ -55,12 +57,12 @@ type
|
||||
procedure TimerSpinEditChange(Sender: TObject);
|
||||
private
|
||||
serialThr: SerialThread;
|
||||
serialPort: TBlockSerial;
|
||||
function isSerialConnected(): boolean;
|
||||
procedure CloseSerial();
|
||||
procedure OnSerialClose();
|
||||
procedure processReceivedSerialData(Data: string);
|
||||
procedure showWarnBox(message: string);
|
||||
function ConfigureSerial(serial: TBlockSerial): boolean;
|
||||
function ConfigureSerial(serial: SerialThread): boolean;
|
||||
procedure OnSerialConnected();
|
||||
procedure OnSerialConnectedFailed();
|
||||
public
|
||||
constructor Create(TheOwner: TComponent); override;
|
||||
end;
|
||||
@@ -85,23 +87,20 @@ end;
|
||||
|
||||
procedure SerialPortFrame.SerialParamComboBoxEditingDone(Sender: TObject);
|
||||
begin
|
||||
if isSerialConnected() then
|
||||
ConfigureSerial(serialPort);
|
||||
if (serialThr <> nil) and serialThr.isConnected() then
|
||||
ConfigureSerial(serialThr);
|
||||
end;
|
||||
|
||||
|
||||
|
||||
procedure SerialPortFrame.closeButtonClick(Sender: TObject);
|
||||
begin
|
||||
CloseSerial();
|
||||
openButton.Enabled := True;
|
||||
serialComboBox.Enabled := True;
|
||||
serialThr.Close();
|
||||
end;
|
||||
|
||||
procedure SerialPortFrame.FormClose(Sender: TObject; var CloseAction: TCloseAction);
|
||||
begin
|
||||
CloseSerial();
|
||||
FreeAndNil(serialPort);
|
||||
serialThr.Close();
|
||||
end;
|
||||
|
||||
|
||||
@@ -109,32 +108,20 @@ end;
|
||||
procedure SerialPortFrame.OpenButtonClick(Sender: TObject);
|
||||
|
||||
begin
|
||||
|
||||
openButton.Enabled := False; // 防止多次点击
|
||||
serialPort := TBlockSerial.Create();
|
||||
serialPort.Connect(serialComboBox.Text);
|
||||
if not ConfigureSerial(serialPort) then
|
||||
|
||||
serialThr := SerialThread.Create(True, serialComboBox.Text);
|
||||
serialThr.OnConnected := @OnSerialConnected;
|
||||
serialThr.OnConnectedFailed := @OnSerialConnectedFailed;
|
||||
serialThr.OnRecvData := @processReceivedSerialData;
|
||||
serialThr.OnClosed := @OnSerialClose;
|
||||
if not ConfigureSerial(serialThr) then
|
||||
begin
|
||||
FreeAndNil(serialThr);
|
||||
Exit;
|
||||
end;
|
||||
if isSerialConnected() then
|
||||
begin
|
||||
//serialPort.Config(baudrate, databit, paritybit, stopbit,
|
||||
// False, False);
|
||||
serialThr := SerialThread.Create(True, serialPort);
|
||||
serialThr.OnRecvData := @processReceivedSerialData;
|
||||
serialThr.Start;
|
||||
serialComboBox.Enabled := False;
|
||||
openButton.Enabled := False;
|
||||
closeButton.Enabled := True;
|
||||
end
|
||||
else
|
||||
begin
|
||||
showWarnBox('串口打开失败');
|
||||
openButton.Enabled := True;
|
||||
closeButton.Enabled := False;
|
||||
CloseSerial();
|
||||
end;
|
||||
serialThr.Start;
|
||||
|
||||
end;
|
||||
|
||||
procedure SerialPortFrame.sendButtonClick(Sender: TObject);
|
||||
@@ -142,16 +129,16 @@ var
|
||||
hexArr: array of char;
|
||||
binBufferLen: integer;
|
||||
begin
|
||||
if isSerialConnected and (SendMemo.GetTextLen > 0) then
|
||||
if (serialThr <> nil) and serialThr.isConnected() and (SendMemo.GetTextLen > 0) then
|
||||
begin
|
||||
if SendEncodingComboBox.ItemIndex = 0 then
|
||||
serialPort.SendString(SendMemo.Text)
|
||||
serialThr.SendString(SendMemo.Text)
|
||||
else
|
||||
begin
|
||||
SetLength(hexArr, SendMemo.GetTextLen div 2);
|
||||
binBufferLen := HexToBin(PChar(SendMemo.Text), PChar(hexArr),
|
||||
SendMemo.GetTextLen div 2);
|
||||
serialPort.SendBuffer(PChar(hexArr), binBufferLen);
|
||||
serialThr.SendBuffer(PChar(hexArr), binBufferLen);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
@@ -181,7 +168,7 @@ begin
|
||||
openButton.Enabled := True;
|
||||
end;
|
||||
// 设置按钮状态
|
||||
if isSerialConnected() then
|
||||
if (serialThr <> nil) and serialThr.isConnected() then
|
||||
begin
|
||||
openButton.Enabled := False;
|
||||
sendButton.Enabled := True;
|
||||
@@ -220,21 +207,11 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
function SerialPortFrame.isSerialConnected: boolean;
|
||||
procedure SerialPortFrame.OnSerialClose;
|
||||
begin
|
||||
Result := ((serialPort <> nil) and serialPort.InstanceActive);
|
||||
end;
|
||||
|
||||
procedure SerialPortFrame.CloseSerial;
|
||||
begin
|
||||
if isSerialConnected() then
|
||||
begin
|
||||
closeButton.Enabled := False;
|
||||
serialPort.Purge();
|
||||
serialPort.CloseSocket();
|
||||
serialThr.Terminate();
|
||||
FreeAndNil(serialPort);
|
||||
end;
|
||||
closeButton.Enabled := False;
|
||||
openButton.Enabled := True;
|
||||
serialComboBox.Enabled := True;
|
||||
end;
|
||||
|
||||
procedure SerialPortFrame.processReceivedSerialData(Data: string);
|
||||
@@ -275,7 +252,7 @@ begin
|
||||
box.ShowModal;
|
||||
end;
|
||||
|
||||
function SerialPortFrame.ConfigureSerial(serial: TBlockSerial): boolean;
|
||||
function SerialPortFrame.ConfigureSerial(serial: SerialThread): boolean;
|
||||
var
|
||||
baudRate: integer;
|
||||
databit: integer;
|
||||
@@ -307,16 +284,30 @@ begin
|
||||
//else
|
||||
// stopbit := SB1;
|
||||
end;
|
||||
serialThr.ConfigureSerial(baudRate, databit, paritybit, stopbit, False, False);
|
||||
Exit(True);
|
||||
end;
|
||||
|
||||
procedure SerialPortFrame.OnSerialConnected;
|
||||
begin
|
||||
serialComboBox.Enabled := False;
|
||||
openButton.Enabled := False;
|
||||
closeButton.Enabled := True;
|
||||
ConfigureSerial(serialThr);
|
||||
end;
|
||||
|
||||
procedure SerialPortFrame.OnSerialConnectedFailed;
|
||||
begin
|
||||
showWarnBox('串口打开失败');
|
||||
openButton.Enabled := True;
|
||||
closeButton.Enabled := False;
|
||||
end;
|
||||
|
||||
constructor SerialPortFrame.Create(TheOwner: TComponent);
|
||||
begin
|
||||
inherited Create(TheOwner);
|
||||
serialPort := TBlockSerial.Create;
|
||||
// 接收到\n即换行
|
||||
RecvMemo.Lines.TextLineBreakStyle := tlbsLF;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user