initial commit: basic serial communication

This commit is contained in:
2023-11-15 22:25:00 +08:00
commit c0da7ba0ce
7 changed files with 1188 additions and 0 deletions
+30
View File
@@ -0,0 +1,30 @@
# Lazarus compiler-generated binaries (safe to delete)
*.exe
*.dll
*.so
*.dylib
*.lrs
*.res
*.compiled
*.dbg
*.ppu
*.o
*.or
*.a
# Lazarus autogenerated files (duplicated info)
*.rst
*.rsj
*.lrt
# Lazarus local files (user-specific info)
*.lps
# Lazarus backups and unit output folders.
# These can be changed by user in Lazarus/project options.
backup/
*.bak
lib/
# Application bundle for Mac OS
*.app/
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

+164
View File
@@ -0,0 +1,164 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="12"/>
<PathDelim Value="\"/>
<General>
<SessionStorage Value="InProjectDir"/>
<Title Value="SerialAsst"/>
<Scaled Value="True"/>
<ResourceType Value="res"/>
<UseXPManifest Value="True"/>
<XPManifest>
<DpiAware Value="True"/>
</XPManifest>
<Icon Value="0"/>
</General>
<BuildModes>
<Item Name="Default" Default="True"/>
<Item Name="Debug">
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<Target>
<Filename Value="SerialAsst-debug"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)-debug"/>
</SearchPaths>
<Parsing>
<SyntaxOptions>
<IncludeAssertionCode Value="True"/>
</SyntaxOptions>
</Parsing>
<CodeGeneration>
<Checks>
<IOChecks Value="True"/>
<RangeChecks Value="True"/>
<OverflowChecks Value="True"/>
<StackChecks Value="True"/>
</Checks>
<VerifyObjMethodCallValidity Value="True"/>
<TargetCPU Value="x86_64"/>
</CodeGeneration>
<Linking>
<Debugging>
<DebugInfoType Value="dsDwarf3"/>
<UseHeaptrc Value="True"/>
<TrashVariables Value="True"/>
<UseExternalDbgSyms Value="True"/>
</Debugging>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
</CompilerOptions>
</Item>
<Item Name="Release">
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<Target>
<Filename Value="SerialAsst-release"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)-Release"/>
</SearchPaths>
<CodeGeneration>
<SmartLinkUnit Value="True"/>
<TargetCPU Value="x86_64"/>
<Optimizations>
<OptimizationLevel Value="3"/>
</Optimizations>
<SmallerCode Value="True"/>
</CodeGeneration>
<Linking>
<Debugging>
<GenerateDebugInfo Value="False"/>
</Debugging>
<LinkSmart Value="True"/>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
</CompilerOptions>
</Item>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<UseFileFilters Value="True"/>
</PublishOptions>
<RunParams>
<FormatVersion Value="2"/>
</RunParams>
<RequiredPackages>
<Item>
<PackageName Value="LazControls"/>
</Item>
<Item>
<PackageName Value="laz_synapse"/>
</Item>
<Item>
<PackageName Value="LCL"/>
</Item>
</RequiredPackages>
<Units>
<Unit>
<Filename Value="SerialAsst.lpr"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="mainunit.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="MainForm"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
</Unit>
<Unit>
<Filename Value="serialmanager.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="SerialManager"/>
</Unit>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<Target>
<Filename Value="SerialAsst"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<Linking>
<Debugging>
<DebugInfoType Value="dsDwarf3"/>
</Debugging>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
</CompilerOptions>
<Debugging>
<Exceptions>
<Item>
<Name Value="EAbort"/>
</Item>
<Item>
<Name Value="ECodetoolError"/>
</Item>
<Item>
<Name Value="EFOpenError"/>
</Item>
</Exceptions>
</Debugging>
</CONFIG>
+24
View File
@@ -0,0 +1,24 @@
program SerialAsst;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}
cthreads,
{$ENDIF} {$IFDEF HASAMIGA}
athreads,
{$ENDIF}
Interfaces, // this includes the LCL widgetset
Forms, lazcontrols,
mainunit,
SerialManager { you can add units after this };
{$R *.res}
begin
RequireDerivedFormResource := True;
Application.Scaled := True;
Application.Initialize;
Application.CreateForm(TMainForm, MainForm);
Application.Run;
end.
+618
View File
@@ -0,0 +1,618 @@
object MainForm: TMainForm
Left = 414
Height = 550
Top = 318
Width = 900
Caption = 'MainForm'
ClientHeight = 550
ClientWidth = 900
Font.CharSet = ANSI_CHARSET
Font.Height = -16
Font.Name = 'Segoe UI'
Font.Pitch = fpVariable
Font.Quality = fqDraft
OnClose = FormClose
object MainPageControl: TPageControl
AnchorSideLeft.Control = Owner
AnchorSideTop.Control = Owner
AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = Owner
AnchorSideBottom.Side = asrBottom
Left = 10
Height = 530
Top = 10
Width = 880
ActivePage = SerialTabSheet
Anchors = [akTop, akLeft, akRight, akBottom]
BorderSpacing.Left = 10
BorderSpacing.Top = 10
BorderSpacing.Right = 10
BorderSpacing.Bottom = 10
Font.CharSet = ANSI_CHARSET
Font.Height = -16
Font.Name = 'Microsoft YaHei UI'
Font.Pitch = fpVariable
Font.Quality = fqDraft
ParentFont = False
TabIndex = 0
TabOrder = 0
object SerialTabSheet: TTabSheet
Caption = '串口'
ClientHeight = 496
ClientWidth = 872
object SerialGroupBox: TGroupBox
AnchorSideLeft.Control = Owner
AnchorSideTop.Control = SerialTabSheet
AnchorSideBottom.Control = SerialTabSheet
AnchorSideBottom.Side = asrBottom
Left = 20
Height = 466
Top = 20
Width = 180
Anchors = [akTop, akLeft, akBottom]
BorderSpacing.Left = 20
BorderSpacing.Top = 20
BorderSpacing.Bottom = 10
BorderSpacing.InnerBorder = 1
Caption = '参数设置'
ClientHeight = 440
ClientWidth = 176
Font.CharSet = ANSI_CHARSET
Font.Height = -16
Font.Name = 'Microsoft YaHei UI'
Font.Pitch = fpVariable
Font.Quality = fqDraft
ParentFont = False
ParentShowHint = False
ShowHint = True
TabOrder = 0
object serialLabel: TLabel
AnchorSideLeft.Control = SerialGroupBox
AnchorSideTop.Control = paritybitComboBox
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = serialComboBox
AnchorSideBottom.Control = openButton
Left = 5
Height = 23
Top = 342
Width = 51
Anchors = [akLeft, akBottom]
AutoSize = False
BorderSpacing.Left = 5
BorderSpacing.Top = 40
BorderSpacing.Right = 20
BorderSpacing.Bottom = 30
Caption = '串 口'
Font.CharSet = GB2312_CHARSET
Font.Height = -16
Font.Pitch = fpVariable
Font.Quality = fqDraft
Layout = tlCenter
ParentColor = False
ParentFont = False
end
object serialComboBox: TComboBox
AnchorSideLeft.Control = serialLabel
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = serialLabel
AnchorSideTop.Side = asrCenter
Left = 76
Height = 29
Top = 339
Width = 88
AutoSize = False
BorderSpacing.Left = 5
BorderSpacing.Top = 25
ItemHeight = 21
ParentShowHint = False
ReadOnly = True
ShowHint = True
Style = csDropDownList
TabOrder = 0
TextHint = '(无)'
end
object paritybitLabel: TLabel
AnchorSideLeft.Control = SerialGroupBox
AnchorSideTop.Control = stopbitLabel
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = paritybitComboBox
Left = 5
Height = 23
Top = 179
Width = 51
AutoSize = False
BorderSpacing.Left = 5
BorderSpacing.Top = 30
BorderSpacing.Right = 20
BorderSpacing.Bottom = 1
Caption = '校验位'
Font.CharSet = GB2312_CHARSET
Font.Height = -16
Font.Pitch = fpVariable
Font.Quality = fqDraft
Layout = tlCenter
ParentColor = False
ParentFont = False
end
object paritybitComboBox: TComboBox
AnchorSideLeft.Control = paritybitLabel
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = paritybitLabel
AnchorSideTop.Side = asrCenter
Left = 76
Height = 29
Top = 176
Width = 88
AutoSize = False
BorderSpacing.Left = 5
BorderSpacing.Top = 20
ItemHeight = 21
ItemIndex = 0
Items.Strings = (
'无'
'奇校验'
'偶校验'
)
ReadOnly = True
Style = csDropDownList
TabOrder = 4
Text = '无'
end
object databitLabel: TLabel
AnchorSideLeft.Control = SerialGroupBox
AnchorSideTop.Control = baudrateLabel
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = databitComboBox
Left = 5
Height = 23
Top = 73
Width = 51
AutoSize = False
BorderSpacing.Left = 5
BorderSpacing.Top = 30
BorderSpacing.Right = 20
BorderSpacing.Bottom = 1
Caption = '数据位'
Font.CharSet = GB2312_CHARSET
Font.Height = -16
Font.Pitch = fpVariable
Font.Quality = fqDraft
Layout = tlCenter
ParentColor = False
ParentFont = False
end
object databitComboBox: TComboBox
AnchorSideLeft.Control = databitLabel
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = databitLabel
AnchorSideTop.Side = asrCenter
Left = 76
Height = 29
Top = 70
Width = 90
AutoSize = False
BorderSpacing.Left = 5
BorderSpacing.Top = 20
ItemHeight = 21
ItemIndex = 0
Items.Strings = (
'8'
'7'
'6'
'5'
)
ReadOnly = True
Style = csDropDownList
TabOrder = 2
Text = '8'
end
object stopbitLabel: TLabel
AnchorSideLeft.Control = SerialGroupBox
AnchorSideTop.Control = databitLabel
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = stopbitComboBox
Left = 5
Height = 23
Top = 126
Width = 51
AutoSize = False
BorderSpacing.Left = 5
BorderSpacing.Top = 30
BorderSpacing.Right = 20
BorderSpacing.Bottom = 1
Caption = '停止位'
Font.CharSet = GB2312_CHARSET
Font.Height = -16
Font.Pitch = fpVariable
Font.Quality = fqDraft
Layout = tlCenter
ParentColor = False
ParentFont = False
end
object stopbitComboBox: TComboBox
AnchorSideLeft.Control = stopbitLabel
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = stopbitLabel
AnchorSideTop.Side = asrCenter
Left = 76
Height = 29
Top = 123
Width = 90
AutoSize = False
BorderSpacing.Left = 5
BorderSpacing.Top = 20
ItemHeight = 21
ItemIndex = 2
Items.Strings = (
'2'
'1.5'
'1'
)
ReadOnly = True
Style = csDropDownList
TabOrder = 3
Text = '1'
end
object baudrateLabel: TLabel
AnchorSideLeft.Control = SerialGroupBox
AnchorSideTop.Control = SerialGroupBox
AnchorSideRight.Control = baudrateComboBox
Left = 5
Height = 23
Top = 20
Width = 51
AutoSize = False
BorderSpacing.Left = 5
BorderSpacing.Top = 20
BorderSpacing.Right = 20
BorderSpacing.Bottom = 1
Caption = '波特率'
Font.CharSet = ANSI_CHARSET
Font.Height = -16
Font.Name = 'Microsoft YaHei UI'
Font.Pitch = fpVariable
Font.Quality = fqDraft
Layout = tlCenter
ParentColor = False
ParentFont = False
end
object baudrateComboBox: TComboBox
AnchorSideLeft.Control = baudrateLabel
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = baudrateLabel
AnchorSideTop.Side = asrCenter
Left = 76
Height = 29
Top = 17
Width = 88
AutoSize = False
BorderSpacing.Left = 5
ItemHeight = 21
ItemIndex = 3
Items.Strings = (
'256000'
'230400'
'128000'
'115200'
'76800'
'57600'
'43000'
'38400'
'19200'
'14400'
'9600'
'4800'
'2400'
'1200'
)
TabOrder = 1
Text = '115200'
end
object openButton: TButton
AnchorSideBottom.Control = SerialGroupBox
AnchorSideBottom.Side = asrBottom
Left = 5
Height = 25
Top = 395
Width = 75
Anchors = [akLeft, akBottom]
BorderSpacing.Bottom = 20
Caption = '打开'
Enabled = False
Font.Height = -16
OnClick = openButtonClick
ParentFont = False
TabOrder = 5
end
object closeButton: TButton
AnchorSideBottom.Control = SerialGroupBox
AnchorSideBottom.Side = asrBottom
Left = 91
Height = 25
Top = 395
Width = 75
Anchors = [akLeft, akBottom]
BorderSpacing.Bottom = 20
Caption = '关闭'
Enabled = False
Font.Height = -16
OnClick = closeButtonClick
ParentFont = False
TabOrder = 6
end
end
object RecvMemo: TMemo
AnchorSideLeft.Control = SerialGroupBox
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = SerialTabSheet
AnchorSideRight.Control = SerialSendGroupBox
AnchorSideBottom.Control = SendMemo
Left = 208
Height = 321
Top = 28
Width = 462
Anchors = [akTop, akLeft, akRight, akBottom]
BorderSpacing.Left = 20
BorderSpacing.Top = 28
BorderSpacing.Right = 10
BorderSpacing.Bottom = 10
Font.CharSet = ANSI_CHARSET
Font.Height = -16
Font.Name = 'Consolas'
Font.Pitch = fpFixed
Font.Quality = fqDraft
ParentFont = False
ReadOnly = True
ScrollBars = ssAutoVertical
TabOrder = 1
WantTabs = True
end
object SendMemo: TMemo
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = SerialSendGroupBox
AnchorSideBottom.Control = sendButton
Left = 208
Height = 97
Top = 359
Width = 462
Anchors = [akLeft, akRight, akBottom]
BorderSpacing.Top = 10
BorderSpacing.Right = 10
BorderSpacing.Bottom = 5
ParentShowHint = False
TabOrder = 2
end
object SerialSendGroupBox: TGroupBox
AnchorSideRight.Control = SerialTabSheet
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = SerialTabSheet
AnchorSideBottom.Side = asrBottom
Left = 680
Height = 137
Top = 349
Width = 172
Anchors = [akRight, akBottom]
BorderSpacing.Right = 20
BorderSpacing.Bottom = 10
Caption = '发送设置'
ClientHeight = 111
ClientWidth = 168
Font.CharSet = ANSI_CHARSET
Font.Height = -16
Font.Name = 'Microsoft YaHei UI'
Font.Pitch = fpVariable
Font.Quality = fqDraft
ParentFont = False
TabOrder = 4
object SendEncodingLabel: TLabel
AnchorSideLeft.Control = SerialSendGroupBox
AnchorSideTop.Control = SerialSendGroupBox
Left = 10
Height = 23
Top = 10
Width = 38
AutoSize = False
BorderSpacing.Left = 10
BorderSpacing.Top = 10
Caption = '编码'
Font.CharSet = GB2312_CHARSET
Font.Height = -16
Font.Pitch = fpVariable
Font.Quality = fqDraft
ParentColor = False
ParentFont = False
end
object SendEncodingComboBox: TComboBox
AnchorSideLeft.Control = SendEncodingLabel
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = SendEncodingLabel
AnchorSideTop.Side = asrCenter
Left = 58
Height = 29
Top = 7
Width = 100
Anchors = [akTop, akLeft, akBottom]
AutoSize = False
BorderSpacing.Left = 10
Font.Height = -16
ItemHeight = 21
ItemIndex = 0
Items.Strings = (
'UTF-8'
'HEX'
)
ParentFont = False
ReadOnly = True
Style = csDropDownList
TabOrder = 0
Text = 'UTF-8'
end
end
object RecvGroupBox: TGroupBox
AnchorSideTop.Control = SerialTabSheet
AnchorSideRight.Control = SerialTabSheet
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = SerialSendGroupBox
Left = 680
Height = 319
Top = 20
Width = 172
Anchors = [akTop, akRight, akBottom]
BorderSpacing.Top = 20
BorderSpacing.Right = 20
BorderSpacing.Bottom = 10
Caption = '接收设置'
ClientHeight = 293
ClientWidth = 168
Font.CharSet = ANSI_CHARSET
Font.Height = -16
Font.Name = 'Microsoft YaHei UI'
Font.Pitch = fpVariable
Font.Quality = fqDraft
ParentFont = False
TabOrder = 3
object ClearButton: TButton
Left = 48
Height = 25
Top = 48
Width = 75
Caption = '清除'
Font.Height = -16
OnClick = clearButtonClick
ParentFont = False
TabOrder = 1
end
object RecvEncodingLabel: TLabel
AnchorSideLeft.Control = RecvGroupBox
AnchorSideTop.Control = RecvGroupBox
Left = 10
Height = 23
Top = 10
Width = 38
AutoSize = False
BorderSpacing.Left = 10
BorderSpacing.Top = 10
Caption = '编码'
Font.CharSet = GB2312_CHARSET
Font.Height = -16
Font.Pitch = fpVariable
Font.Quality = fqDraft
ParentColor = False
ParentFont = False
end
object RecvEncodingComboBox: TComboBox
AnchorSideLeft.Control = RecvEncodingLabel
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = RecvEncodingLabel
AnchorSideTop.Side = asrCenter
Left = 58
Height = 29
Top = 7
Width = 100
AutoSize = False
BorderSpacing.Left = 10
Font.Height = -16
ItemHeight = 21
ItemIndex = 0
Items.Strings = (
'UTF-8'
'HEX'
)
ParentFont = False
ReadOnly = True
Style = csDropDownList
TabOrder = 0
Text = 'UTF-8'
end
end
object sendButton: TButton
AnchorSideLeft.Control = SerialSendGroupBox
AnchorSideTop.Control = SendEncodingLabel
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = SerialSendGroupBox
AnchorSideBottom.Control = SerialTabSheet
AnchorSideBottom.Side = asrBottom
Left = 585
Height = 25
Top = 461
Width = 75
Anchors = [akRight, akBottom]
BorderSpacing.Left = 10
BorderSpacing.Top = 5
BorderSpacing.Right = 20
BorderSpacing.Bottom = 10
Caption = '发送'
Enabled = False
Font.Height = -16
OnClick = sendButtonClick
ParentFont = False
TabOrder = 5
end
object TimerCheckBox: TCheckBox
AnchorSideTop.Control = TimerSpinEdit
AnchorSideTop.Side = asrCenter
AnchorSideRight.Control = TimerSpinEdit
Left = 396
Height = 23
Top = 462
Width = 78
Anchors = [akTop, akRight]
BorderSpacing.Right = 5
Caption = '定时发送'
Font.CharSet = ANSI_CHARSET
Font.Height = -14
Font.Name = 'Segoe UI'
Font.Pitch = fpVariable
Font.Quality = fqDraft
OnChange = TimerCheckBoxChange
ParentFont = False
TabOrder = 6
end
object TimerSpinEdit: TSpinEdit
AnchorSideTop.Control = MSLabel
AnchorSideTop.Side = asrCenter
AnchorSideRight.Control = MSLabel
Left = 479
Height = 29
Top = 459
Width = 69
Anchors = [akTop, akRight]
BorderSpacing.Right = 5
MaxValue = 2147483647
MinValue = 1
OnChange = TimerSpinEditChange
TabOrder = 7
Value = 1000
end
object MSLabel: TLabel
AnchorSideTop.Control = sendButton
AnchorSideTop.Side = asrCenter
AnchorSideRight.Control = sendButton
Left = 553
Height = 21
Top = 463
Width = 22
Anchors = [akTop, akRight]
BorderSpacing.Right = 10
Caption = 'ms'
ParentColor = False
end
end
object TabSheet2: TTabSheet
Caption = 'Socket'
end
end
object SerialListTimer: TTimer
Interval = 500
OnTimer = SerialListTimerTimer
Left = 336
Top = 8
end
object SerialSendTimer: TTimer
Enabled = False
OnTimer = SerialSendTimerTimer
Left = 470
Top = 18
end
end
+294
View File
@@ -0,0 +1,294 @@
unit mainunit;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls,
ComCtrls, Spin, SpinEx, Synaser, SerialManager, Types;
type
{ TMainForm }
TMainForm = class(TForm)
baudrateComboBox: TComboBox;
TimerCheckBox: TCheckBox;
closeButton: TButton;
MSLabel: TLabel;
RecvGroupBox: TGroupBox;
SendEncodingComboBox: TComboBox;
RecvEncodingComboBox: TComboBox;
RecvEncodingLabel: TLabel;
SerialSendGroupBox: TGroupBox;
SendEncodingLabel: TLabel;
MainPageControl: TPageControl;
SerialGroupBox: TGroupBox;
RecvMemo: TMemo;
openButton: TButton;
databitComboBox: TComboBox;
databitLabel: TLabel;
SendMemo: TMemo;
sendButton: TButton;
ClearButton: TButton;
SerialSendTimer: TTimer;
TimerSpinEdit: TSpinEdit;
stopbitComboBox: TComboBox;
baudrateLabel: TLabel;
paritybitComboBox: TComboBox;
serialComboBox: TComboBox;
stopbitLabel: TLabel;
paritybitLabel: TLabel;
serialLabel: TLabel;
SerialListTimer: TTimer;
SerialTabSheet: TTabSheet;
TabSheet2: TTabSheet;
procedure ClearButtonClick(Sender: TObject);
procedure closeButtonClick(Sender: TObject);
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
procedure openButtonClick(Sender: TObject);
procedure sendButtonClick(Sender: TObject);
procedure SerialListTimerTimer(Sender: TObject);
procedure SerialSendTimerTimer(Sender: TObject);
procedure TimerCheckBoxChange(Sender: TObject);
procedure TimerSpinEditChange(Sender: TObject);
private
serialThr: SerialThread;
serialPort: TBlockSerial;
function isSerialConnected(): boolean;
procedure closeSerial();
procedure processReceivedSerialData(Data: string);
procedure showWarnBox(message: string);
public
constructor Create(TheOwner: TComponent); override;
end;
var
MainForm: TMainForm;
implementation
{$R *.lfm}
{ TMainForm }
procedure TMainForm.ClearButtonClick(Sender: TObject);
begin
RecvMemo.Clear();
end;
procedure TMainForm.closeButtonClick(Sender: TObject);
begin
closeSerial();
openButton.Enabled := True;
serialComboBox.Enabled := True;
end;
procedure TMainForm.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
closeSerial();
FreeAndNil(serialPort);
end;
procedure TMainForm.openButtonClick(Sender: TObject);
var
baudRate: integer;
databit: integer;
paritybit: char;
stopbit: integer;
begin
if TryStrToInt(baudrateComboBox.Text, baudRate) then
baudrate := StrToInt(baudrateComboBox.Text)
else
begin
showWarnBox('波特率参数错误');
Exit;
end;
databit := StrToInt(databitComboBox.Text);
case (paritybitComboBox.Text) of
'无': paritybit := 'N';
'奇校验': paritybit := 'O';
'偶校验': paritybit := 'E';
else
paritybit := 'N';
end;
case (stopbitComboBox.Text) of
'1': stopbit := SB1;
'1.5': stopbit := SB1andHalf;
'2': stopbit := SB2;
//else
// stopbit := SB1;
end;
openButton.Enabled := False; // 防止多次点击
serialPort.Connect(serialComboBox.Text);
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;
end
else
begin
showWarnBox('串口打开失败');
openButton.Enabled := True;
closeButton.Enabled := False;
end;
end;
procedure TMainForm.sendButtonClick(Sender: TObject);
var
hexArr: array of char;
binBufferLen: integer;
begin
if isSerialConnected and (SendMemo.GetTextLen > 0) then
begin
if SendEncodingComboBox.ItemIndex = 0 then
serialPort.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);
end;
end;
end;
procedure TMainForm.SerialListTimerTimer(Sender: TObject);
var
serialList: string;
begin
// 刷新串口列表
serialList := GetSerialPortNames;
if (serialList.IsEmpty) then
begin
// 只在当前Combox非空时Clear,防止闪烁
if not (serialComboBox.Items.CommaText.IsEmpty) then
begin
serialComboBox.Items.Clear;
end;
openButton.Enabled := False;
end
else
begin
if not (serialComboBox.Items.CommaText.Equals(serialList)) then
begin
serialComboBox.Items.CommaText := serialList;
serialComboBox.ItemIndex := 0;
end;
openButton.Enabled := True;
end;
// 设置按钮状态
if isSerialConnected() then
begin
openButton.Enabled := False;
sendButton.Enabled := True;
closeButton.Enabled := True;
end
else
begin
sendButton.Enabled := False;
closeButton.Enabled := False;
end;
end;
procedure TMainForm.SerialSendTimerTimer(Sender: TObject);
begin
sendButtonClick(Sender);
end;
procedure TMainForm.TimerCheckBoxChange(Sender: TObject);
begin
if (Sender is TCheckBox) then
begin
if (Sender as TCheckBox).Checked then
begin
SerialSendTimer.Enabled := True;
end
else
begin
SerialSendTimer.Enabled := False;
end;
end;
end;
procedure TMainForm.TimerSpinEditChange(Sender: TObject);
begin
SerialSendTimer.Interval := TimerSpinEdit.Value;
end;
function TMainForm.isSerialConnected: boolean;
begin
Result := ((serialPort <> nil) and serialPort.InstanceActive);
end;
procedure TMainForm.closeSerial;
begin
if isSerialConnected() then
begin
closeButton.Enabled := False;
serialPort.Purge();
serialPort.CloseSocket();
serialThr.Terminate();
end;
end;
procedure TMainForm.processReceivedSerialData(Data: string);
var
hexArr: array of char;
hexResult: string;
i: integer;
begin
RecvMemo.SelStart := Length(RecvMemo.Text);
if RecvEncodingComboBox.ItemIndex = 0 then
begin
{ TODO -omycai : 将各类换行符换成LineBreak }
RecvMemo.SelText := Data;
end
else
begin
hexResult := '';
SetLength(hexArr, Data.Length * 2);
BinToHex(Pointer(Data), PChar(hexArr), Data.Length);
for i := 0 to High(hexArr) div 2 do
hexResult := hexResult + hexArr[i * 2] + hexArr[i * 2 + 1] + ':';
RecvMemo.SelText := ansistring(hexResult);
end;
end;
procedure TMainForm.showWarnBox(message: string);
var
box: TForm;
begin
box := CreateMessageDialog(message, mtWarning, [mbClose]);
box.Position := poOwnerFormCenter;
box.ShowModal;
end;
constructor TMainForm.Create(TheOwner: TComponent);
begin
inherited Create(TheOwner);
serialPort := TBlockSerial.Create;
// 接收到\n即换行
RecvMemo.Lines.TextLineBreakStyle := tlbsLF;
end;
end.
+58
View File
@@ -0,0 +1,58 @@
unit SerialManager;
{$mode ObjFPC}{$H+}
{$m+}
interface
uses
Classes, Synaser;
type
TRecvDataEvent = procedure(Data: string) of object;
{ SerialThread }
SerialThread = class(TThread)
protected
procedure Execute; override;
procedure ProcessRecvEvent;
private
MserialPort: TBlockSerial;
FOnRecvData: TRecvDataEvent;
currentRecvData: string;
public
constructor Create(CreateSuspended: boolean; serialPort: TBlockSerial);
property OnRecvData: TRecvDataEvent read FOnRecvData write FOnRecvData;
end;
implementation
constructor SerialThread.Create(CreateSuspended: boolean; serialPort: TBlockSerial);
begin
inherited Create(CreateSuspended);
FreeOnTerminate := True;
Self.MserialPort := serialPort;
end;
procedure SerialThread.Execute;
begin
while not (Terminated) do
begin
currentRecvData := MserialPort.RecvPacket(-1);
Synchronize(@ProcessRecvEvent);
end;
end;
procedure SerialThread.ProcessRecvEvent;
begin
if Assigned(FOnRecvData) then
begin
FOnRecvData(currentRecvData);
end;
end;
end.