{*****************************************************************************
*本单元说明:串口通信封装类
****************************************************************************}
unit COMDevIO;
interface
uses
SysUtils, Forms, CPort;
type
TOnDataReceived = procedure(const AStr: string) of object;
type
TCOMDevIO = class
private
//串口通信对象
fPort: TComPort;
//串口通信接收对象
fPortDataPacket: TComDataPacket;
//数据接收回调函数
fOnDataReceived: TOnDataReceived;
private
//数据接收处理
procedure PortDataPacketPacket(Sender: TObject; const Str: String);
public
//创建
constructor Create(ACOM: Byte);
//设置通信参数
procedure setParameters(ACOM: Byte; ABaudRate: TBaudRate = br9600;
ADataBits: TDataBits = dbSeven; AParityBit: TParityBits = prOdd;
AParityCheck: Boolean = True; AStopBit: TStopBits = sbTwoStopBits);
//设置通信超时
procedure setWriteTotal(t: Integer);
//打开串口
function openCOM(ACOM: Byte): Boolean;
//关闭串口
procedure close;
//发送数据
function sendData(const AStr: string): Boolean;
//设置数据接收函数
procedure setOnDataReceived(AOnDataReceived: TOnDataReceived);
end;
implementation
uses
LogUnit;
{ TCOMDevIO }
constructor TCOMDevIO.Create(ACOM: Byte);
begin
fPort := TComPort.Create(Application.MainForm);
if ACOM > 0 then
begin
fPort.Port := 'COM' + IntToStr(ACOM);
end;
fPort.BaudRate := br9600;
fPort.DataBits := dbSeven;
fPort.StopBits := sbTwoStopBits;
fPort.Parity.Bits := prOdd;
fPort.Parity.Check := TRUE;
fPort.DiscardNull := FALSE ;
fPort.EventChar := #13;
fPort.Events := [evRxChar];
fPort.Timeouts.ReadInterval := -1;
fPort.Timeouts.ReadTotalMultiplier := 0;
fPort.Timeouts.ReadTotalConstant := 0;
fPort.Timeouts.WriteTotalConstant := 1000;
fPort.Timeouts.WriteTotalMultiplier := 100;
fPortDataPacket := TComDataPacket.Create(fPort);
fPortDataPacket.OnPacket := PortDataPacketPacket;
fPortDataPacket.ComPort := fPort;
fPortDataPacket.MaxBufferSize := 1024;
fPortDataPacket.CaseInsensitive := False;
fPortDataPacket.IncludeStrings := False;
fPort.SyncMethod := smThreadSync;
end;
procedure TCOMDevIO.setParameters(ACOM: Byte; ABaudRate: TBaudRate = br9600;
ADataBits: TDataBits = dbSeven; AParityBit: TParityBits = prOdd;
AParityCheck: Boolean = True; AStopBit: TStopBits = sbTwoStopBits);
begin
// note: 尽量不要在已打开串口的情况下修改参数
fPort.BaudRate := ABaudRate;
fPort.DataBits := ADataBits;
fPort.Parity.Bits := AParityBit;
fPort.Parity.Check := AParityCheck;
fPort.StopBits := AStopBit;
end;
procedure TCOMDevIO.setWriteTotal(t: Integer);
begin
fPort.Timeouts.WriteTotalConstant := t;
end;
function TCOMDevIO.openCOM(ACOM: Byte): Boolean;
var
Port: TPort;
begin
Result := False;
Port := 'COM' + IntToStr(ACOM);
fPort.Close;
if fPort.Port <> Port then
begin
// note: 如果以前串口已经打开,执行下面的语句会更换串口号后打开串口
fPort.Port := Port;
end;
try
fPort.Open;
Result := fPort.Connected;
except
On E: Exception do
begin
WriteLog(Format('无法打开串口:%d, %s', [ACOM, E.Message]));
end;
end;
end;
procedure TCOMDevIO.close;
begin
fPort.Close;
end;
procedure TCOMDevIO.PortDataPacketPacket(Sender: TObject;
const Str: String);
begin
if Assigned(fOnDataReceived) then
begin
fOnDataReceived(Str);
end;
end;
function TCOMDevIO.sendData(const AStr: string): Boolean;
begin
Result := False;
try
if not fPort.Connected then
begin
Exit;
end;
fPort.WriteStr(AStr);
// ErrorLog('TCOMDevIO.SendData:'+TransHexStr(AStr));
Result := True;
except
On E: Exception do
begin
WriteLog('向串口发送数据出现异常: '+E.Message);
end;
end;
end;
procedure TCOMDevIO.setOnDataReceived(AOnDataReceived: TOnDataReceived);
begin
fOnDataReceived := AOnDataReceived;
end;
end.
*本单元说明:串口通信封装类
****************************************************************************}
unit COMDevIO;
interface
uses
SysUtils, Forms, CPort;
type
TOnDataReceived = procedure(const AStr: string) of object;
type
TCOMDevIO = class
private
//串口通信对象
fPort: TComPort;
//串口通信接收对象
fPortDataPacket: TComDataPacket;
//数据接收回调函数
fOnDataReceived: TOnDataReceived;
private
//数据接收处理
procedure PortDataPacketPacket(Sender: TObject; const Str: String);
public
//创建
constructor Create(ACOM: Byte);
//设置通信参数
procedure setParameters(ACOM: Byte; ABaudRate: TBaudRate = br9600;
ADataBits: TDataBits = dbSeven; AParityBit: TParityBits = prOdd;
AParityCheck: Boolean = True; AStopBit: TStopBits = sbTwoStopBits);
//设置通信超时
procedure setWriteTotal(t: Integer);
//打开串口
function openCOM(ACOM: Byte): Boolean;
//关闭串口
procedure close;
//发送数据
function sendData(const AStr: string): Boolean;
//设置数据接收函数
procedure setOnDataReceived(AOnDataReceived: TOnDataReceived);
end;
implementation
uses
LogUnit;
{ TCOMDevIO }
constructor TCOMDevIO.Create(ACOM: Byte);
begin
fPort := TComPort.Create(Application.MainForm);
if ACOM > 0 then
begin
fPort.Port := 'COM' + IntToStr(ACOM);
end;
fPort.BaudRate := br9600;
fPort.DataBits := dbSeven;
fPort.StopBits := sbTwoStopBits;
fPort.Parity.Bits := prOdd;
fPort.Parity.Check := TRUE;
fPort.DiscardNull := FALSE ;
fPort.EventChar := #13;
fPort.Events := [evRxChar];
fPort.Timeouts.ReadInterval := -1;
fPort.Timeouts.ReadTotalMultiplier := 0;
fPort.Timeouts.ReadTotalConstant := 0;
fPort.Timeouts.WriteTotalConstant := 1000;
fPort.Timeouts.WriteTotalMultiplier := 100;
fPortDataPacket := TComDataPacket.Create(fPort);
fPortDataPacket.OnPacket := PortDataPacketPacket;
fPortDataPacket.ComPort := fPort;
fPortDataPacket.MaxBufferSize := 1024;
fPortDataPacket.CaseInsensitive := False;
fPortDataPacket.IncludeStrings := False;
fPort.SyncMethod := smThreadSync;
end;
procedure TCOMDevIO.setParameters(ACOM: Byte; ABaudRate: TBaudRate = br9600;
ADataBits: TDataBits = dbSeven; AParityBit: TParityBits = prOdd;
AParityCheck: Boolean = True; AStopBit: TStopBits = sbTwoStopBits);
begin
// note: 尽量不要在已打开串口的情况下修改参数
fPort.BaudRate := ABaudRate;
fPort.DataBits := ADataBits;
fPort.Parity.Bits := AParityBit;
fPort.Parity.Check := AParityCheck;
fPort.StopBits := AStopBit;
end;
procedure TCOMDevIO.setWriteTotal(t: Integer);
begin
fPort.Timeouts.WriteTotalConstant := t;
end;
function TCOMDevIO.openCOM(ACOM: Byte): Boolean;
var
Port: TPort;
begin
Result := False;
Port := 'COM' + IntToStr(ACOM);
fPort.Close;
if fPort.Port <> Port then
begin
// note: 如果以前串口已经打开,执行下面的语句会更换串口号后打开串口
fPort.Port := Port;
end;
try
fPort.Open;
Result := fPort.Connected;
except
On E: Exception do
begin
WriteLog(Format('无法打开串口:%d, %s', [ACOM, E.Message]));
end;
end;
end;
procedure TCOMDevIO.close;
begin
fPort.Close;
end;
procedure TCOMDevIO.PortDataPacketPacket(Sender: TObject;
const Str: String);
begin
if Assigned(fOnDataReceived) then
begin
fOnDataReceived(Str);
end;
end;
function TCOMDevIO.sendData(const AStr: string): Boolean;
begin
Result := False;
try
if not fPort.Connected then
begin
Exit;
end;
fPort.WriteStr(AStr);
// ErrorLog('TCOMDevIO.SendData:'+TransHexStr(AStr));
Result := True;
except
On E: Exception do
begin
WriteLog('向串口发送数据出现异常: '+E.Message);
end;
end;
end;
procedure TCOMDevIO.setOnDataReceived(AOnDataReceived: TOnDataReceived);
begin
fOnDataReceived := AOnDataReceived;
end;
end.
begin
fOnDataReceived := AOnDataReceived;
end;这里面没有处理啊?如何调用这个来处理从COM接收到的数据
即procedure xx(const AStr: string);
打开关闭发送都好说,接收的话如何做呢?这个回调函数会在什么情况下发生,接收到数据后,我如何通知调用者呢,谢谢
然后,要使用某对象,最简单的思路就是:对象的创建(Create)->对象的初始化设置参数(setParameters)->对象的应用(此为串口,如果打开就返回此串口,如果没打开,就重新注册生成新的串口,这相当与设计模式中的单例模式,一个类(此处是串口)只能有一个该类的实例(串口对象))->对象的销毁.按照这个思路再重新理解你的代码.