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