unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, inifiles, StdCtrls;
const
// MAXCOMNUM = 2 ; //设置最大支持串口数目
WM_RECEIVEDATA = WM_USER + 1;
type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end; thrRead= class(TThread)
protected
procedure Execute ; Override;
public
constructor Create;
end;
function opencom(comname:Integer):THandle; //串口初始化
function readcom(comname:THandle):String; //读取串口数据
function writecom(comname:THandle;pwrite:PChar):Boolean; //写入串口数据
function closecom(comname:THandle):Boolean; //关闭串口
var
Form1: TForm1;
hComAll: THandle;
hEvent: THandle;
implementationuses Math;{$R *.dfm}procedure thrRead.Execute;
var
TEventMask :DWORD;
TWait :Boolean;
begin
TEventMask:=0;
while not Terminated do
begin
TWait:=WaitCommEvent(hComAll,TEventMask,nil);
if TWait then
begin
WaitForSingleObject(hEvent,INFINITE); // 等待同步事件定位
ResetEvent(hEvent); // 同步事件复位
PostMessage(Form1.Handle,WM_RECEIVEDATA,0,0);//向主进程发送消息
end;
end;
end;constructor thrRead.Create;
begin
FreeOnTerminate :=True;
inherited Create(False);
end;function opencom(comname:Integer):THandle;
var
Tcomname:PChar;
Dcb:TDCB;
Hcom:THandle;
Htimeout:TCommTimeouts;
ini:TIniFile;
begin
Result:=INVALID_HANDLE_VALUE;
ini:=TIniFile.Create(ExtractFilePath(Application.ExeName)+'com.ini');
Tcomname := pchar('com'+IntToStr(comname));
Hcom := CreateFile(Tcomname,GENERIC_READ or GENERIC_WRITE,0,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if Hcom=invalid_handle_value then
begin
MessageBox(0,pchar('Notice : com '+inttostr(comname)+'is a invoild com!'),'notice',MB_OK);
end
else
begin
//通过GetCommState函数填充设备控制块DCB
GetCommState(Hcom,Dcb);
//通过调用SetCommState函数配置串行口的波特率、数据位、停止位和校验位
Dcb.BaudRate:=StrToInt(ini.ReadString('com','BaudRate','')); //每秒位数
Dcb.ByteSize:=StrToInt(ini.ReadString('com','ByteSize','')); //数据位
Dcb.StopBits:=StrToInt(ini.ReadString('com','StopBits','')); //停止位
Dcb.Parity:=StrToInt(ini.ReadString('com','Parity','')); //奇偶校验
SetCommState(Hcom,Dcb);
//设置读写缓冲
SetupComm(Hcom,4096,4096);
// 设置超时
Htimeout.ReadIntervalTimeout:=100;
Htimeout.ReadTotalTimeoutMultiplier:=1;
Htimeout.ReadTotalTimeoutConstant:=100;
Htimeout.WriteTotalTimeoutMultiplier:=1;
Htimeout.WriteTotalTimeoutConstant:=100;
SetCommTimeouts(Hcom,Htimeout);
end;
//指定串行口事件为接收到字符;
SetCommMask(Hcom,EV_RXCHAR);
//返回创建串口设备的句柄
Result:=Hcom;
end;function readcom(comname:THandle):String;
var
ByteToRead:DWORD;
ByteRead:DWORD;
S:String;
begin
ByteToRead:=4096;
ByteRead:=0;
SetLength(s,ByteToRead);
ReadFile(comname,s[1],ByteToRead,ByteRead,nil);
if ByteRead>0 then
begin
SetLength(Result,ByteRead);
Move(s[1],Result[1],ByteRead);
end;
end;function writecom(comname:THandle;pwrite:PChar):Boolean;
var
ByteToWrite:DWORD; // 共需写入数
ByteStartWrite:DWORD; // 从何处开始写入
ByteWrite:DWORD; // 已写入数
Tresult:Boolean;
begin
ByteStartWrite:=0;
ByteWrite:=0;
ByteToWrite:=StrLen(pwrite);
repeat
Tresult:=WriteFile(comname,pwrite[ByteStartWrite],ByteToWrite,ByteWrite,nil);
Dec(ByteToWrite,ByteWrite);
Inc(ByteStartWrite,ByteWrite);
until (ByteToWrite<=0);
Result:=Tresult;
end;function closecom(comname:THandle):Boolean;
begin
Result:=CloseHandle(comname);
end;procedure TForm1.Button1Click(Sender: TObject);
var
ini:TIniFile;
PATCommand:PChar;
comstat:PComStat;
TErrorFlag:DWORD;
ReadResult:String;
begin
Memo1.Lines.Clear;
ini:=TIniFile.Create(ExtractFilePath(Application.ExeName)+'com.ini');
//**********端口初始化********
hComAll:=opencom(StrToInt(ini.ReadString('com','com','')));
if hComAll=INVALID_HANDLE_VALUE then
begin
Memo1.Lines.Add('Open COM'+ini.ReadString('COM','COM','')+' error!');
Exit;
end
else
begin
Memo1.Lines.Add('Open COM'+ini.ReadString('com','com','')+' Success!');
end;
//打开端口监听
hEvent:=CreateEvent(nil,True,False,nil);
thrRead.Create;
Memo1.Lines.Add('COM Listen ThrRead Create Success!');
//向端口写入命令
try
PATCommand:=pchar('at+STX'+chr(13));
writecom(hComAll,PATCommand);
try
PATCommand:=pchar('at+B'+Chr(13));
writecom(hComAll,PATCommand);
try
PATCommand:=pchar('at+ETX'+chr(13));
writecom(hComAll,PATCommand);
except
Memo1.Lines.Add('Write Command error!');
end;
except
Memo1.Lines.Add('Write Command error!');
end;
except
Memo1.Lines.Add('Write Command error!');
end;
{try
PATCommand:=pchar('STX');
if writecom(hComAll,PATCommand) then
begin
PATCommand:=pchar('B');
if writecom(hComAll,PATCommand) then
begin
PATCommand:=pchar('ETX');
If writecom(hComAll,PATCommand) then
begin
Memo1.Lines.Add('Write Command Success!');
end
else
begin
Memo1.Lines.Add('Write Command error!');
end;
end
else
begin
Memo1.Lines.Add('Write Command error!');
end;
end
else
begin
Memo1.Lines.Add('Write Command error!');
end;
except
Memo1.Lines.Add('Write Command error!');
end; }
//******* 获得返回值
ReadResult:='';
GetMem(comstat,SIZEOF(Tcomstat));
ClearCommError(hComAll,TErrorFlag,comstat);
if TErrorFlag>0 then
begin
PurgeComm(hComAll,PURGE_RXABORT and PURGE_RXCLEAR);
end;
if comstat.cbInQue >0 then
ReadResult:=readcom(hComAll);
Memo1.Lines.Add('Listen Result : '+ReadResult);
SetEvent(hEvent);
//******关闭端口
closecom(hComAll);
end;end.
运行后死机,不知道什么问题?
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, inifiles, StdCtrls;
const
// MAXCOMNUM = 2 ; //设置最大支持串口数目
WM_RECEIVEDATA = WM_USER + 1;
type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end; thrRead= class(TThread)
protected
procedure Execute ; Override;
public
constructor Create;
end;
function opencom(comname:Integer):THandle; //串口初始化
function readcom(comname:THandle):String; //读取串口数据
function writecom(comname:THandle;pwrite:PChar):Boolean; //写入串口数据
function closecom(comname:THandle):Boolean; //关闭串口
var
Form1: TForm1;
hComAll: THandle;
hEvent: THandle;
implementationuses Math;{$R *.dfm}procedure thrRead.Execute;
var
TEventMask :DWORD;
TWait :Boolean;
begin
TEventMask:=0;
while not Terminated do
begin
TWait:=WaitCommEvent(hComAll,TEventMask,nil);
if TWait then
begin
WaitForSingleObject(hEvent,INFINITE); // 等待同步事件定位
ResetEvent(hEvent); // 同步事件复位
PostMessage(Form1.Handle,WM_RECEIVEDATA,0,0);//向主进程发送消息
end;
end;
end;constructor thrRead.Create;
begin
FreeOnTerminate :=True;
inherited Create(False);
end;function opencom(comname:Integer):THandle;
var
Tcomname:PChar;
Dcb:TDCB;
Hcom:THandle;
Htimeout:TCommTimeouts;
ini:TIniFile;
begin
Result:=INVALID_HANDLE_VALUE;
ini:=TIniFile.Create(ExtractFilePath(Application.ExeName)+'com.ini');
Tcomname := pchar('com'+IntToStr(comname));
Hcom := CreateFile(Tcomname,GENERIC_READ or GENERIC_WRITE,0,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if Hcom=invalid_handle_value then
begin
MessageBox(0,pchar('Notice : com '+inttostr(comname)+'is a invoild com!'),'notice',MB_OK);
end
else
begin
//通过GetCommState函数填充设备控制块DCB
GetCommState(Hcom,Dcb);
//通过调用SetCommState函数配置串行口的波特率、数据位、停止位和校验位
Dcb.BaudRate:=StrToInt(ini.ReadString('com','BaudRate','')); //每秒位数
Dcb.ByteSize:=StrToInt(ini.ReadString('com','ByteSize','')); //数据位
Dcb.StopBits:=StrToInt(ini.ReadString('com','StopBits','')); //停止位
Dcb.Parity:=StrToInt(ini.ReadString('com','Parity','')); //奇偶校验
SetCommState(Hcom,Dcb);
//设置读写缓冲
SetupComm(Hcom,4096,4096);
// 设置超时
Htimeout.ReadIntervalTimeout:=100;
Htimeout.ReadTotalTimeoutMultiplier:=1;
Htimeout.ReadTotalTimeoutConstant:=100;
Htimeout.WriteTotalTimeoutMultiplier:=1;
Htimeout.WriteTotalTimeoutConstant:=100;
SetCommTimeouts(Hcom,Htimeout);
end;
//指定串行口事件为接收到字符;
SetCommMask(Hcom,EV_RXCHAR);
//返回创建串口设备的句柄
Result:=Hcom;
end;function readcom(comname:THandle):String;
var
ByteToRead:DWORD;
ByteRead:DWORD;
S:String;
begin
ByteToRead:=4096;
ByteRead:=0;
SetLength(s,ByteToRead);
ReadFile(comname,s[1],ByteToRead,ByteRead,nil);
if ByteRead>0 then
begin
SetLength(Result,ByteRead);
Move(s[1],Result[1],ByteRead);
end;
end;function writecom(comname:THandle;pwrite:PChar):Boolean;
var
ByteToWrite:DWORD; // 共需写入数
ByteStartWrite:DWORD; // 从何处开始写入
ByteWrite:DWORD; // 已写入数
Tresult:Boolean;
begin
ByteStartWrite:=0;
ByteWrite:=0;
ByteToWrite:=StrLen(pwrite);
repeat
Tresult:=WriteFile(comname,pwrite[ByteStartWrite],ByteToWrite,ByteWrite,nil);
Dec(ByteToWrite,ByteWrite);
Inc(ByteStartWrite,ByteWrite);
until (ByteToWrite<=0);
Result:=Tresult;
end;function closecom(comname:THandle):Boolean;
begin
Result:=CloseHandle(comname);
end;procedure TForm1.Button1Click(Sender: TObject);
var
ini:TIniFile;
PATCommand:PChar;
comstat:PComStat;
TErrorFlag:DWORD;
ReadResult:String;
begin
Memo1.Lines.Clear;
ini:=TIniFile.Create(ExtractFilePath(Application.ExeName)+'com.ini');
//**********端口初始化********
hComAll:=opencom(StrToInt(ini.ReadString('com','com','')));
if hComAll=INVALID_HANDLE_VALUE then
begin
Memo1.Lines.Add('Open COM'+ini.ReadString('COM','COM','')+' error!');
Exit;
end
else
begin
Memo1.Lines.Add('Open COM'+ini.ReadString('com','com','')+' Success!');
end;
//打开端口监听
hEvent:=CreateEvent(nil,True,False,nil);
thrRead.Create;
Memo1.Lines.Add('COM Listen ThrRead Create Success!');
//向端口写入命令
try
PATCommand:=pchar('at+STX'+chr(13));
writecom(hComAll,PATCommand);
try
PATCommand:=pchar('at+B'+Chr(13));
writecom(hComAll,PATCommand);
try
PATCommand:=pchar('at+ETX'+chr(13));
writecom(hComAll,PATCommand);
except
Memo1.Lines.Add('Write Command error!');
end;
except
Memo1.Lines.Add('Write Command error!');
end;
except
Memo1.Lines.Add('Write Command error!');
end;
{try
PATCommand:=pchar('STX');
if writecom(hComAll,PATCommand) then
begin
PATCommand:=pchar('B');
if writecom(hComAll,PATCommand) then
begin
PATCommand:=pchar('ETX');
If writecom(hComAll,PATCommand) then
begin
Memo1.Lines.Add('Write Command Success!');
end
else
begin
Memo1.Lines.Add('Write Command error!');
end;
end
else
begin
Memo1.Lines.Add('Write Command error!');
end;
end
else
begin
Memo1.Lines.Add('Write Command error!');
end;
except
Memo1.Lines.Add('Write Command error!');
end; }
//******* 获得返回值
ReadResult:='';
GetMem(comstat,SIZEOF(Tcomstat));
ClearCommError(hComAll,TErrorFlag,comstat);
if TErrorFlag>0 then
begin
PurgeComm(hComAll,PURGE_RXABORT and PURGE_RXCLEAR);
end;
if comstat.cbInQue >0 then
ReadResult:=readcom(hComAll);
Memo1.Lines.Add('Listen Result : '+ReadResult);
SetEvent(hEvent);
//******关闭端口
closecom(hComAll);
end;end.
运行后死机,不知道什么问题?
建议用SPComm吧
这个控件挺成熟 我以前用它做过与Modem的通信
在网上可以免费下载
begin
comm1.BaudRate:=4800;//可以在属性窗口设置
comm1.CommName:='com1';//可以在属性窗口设置
try
comm1.StartComm;
except
showmessage('串口打开错误');
end;
end;然后发送数据procedure TForm1.send(sbuf: byte);
begin
if not comm1.WriteCommData(@sbuf,1) then
begin
showmessage('发送错误!');
end;
end;
处理接收事件
[code=Delphi(Pascal)]
procedure TForm1.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
var
rbuf:array of byte;
i:integer;
t:ttime;
begin
setLength(rbuf, BufferLength);
move(Buffer^, PChar(rbuf)^, BufferLength);
memo1.Lines.Add('长度'+inttostr(BufferLength));
for i:=0 to BufferLength-1 do
begin
memo1.Lines.Add(inttostr(rbuf[i]));
end;
end;最后关闭串口
procedure TForm1.FormDestroy(Sender: TObject);
begin
comm1.StopComm;
end;
这是我使用时的设定:
object Comm1: TComm
CommName = 'COM1'
BaudRate = 4800
ParityCheck = False
Outx_CtsFlow = False
Outx_DsrFlow = False
DtrControl = DtrDisable
DsrSensitivity = False
TxContinueOnXoff = False
Outx_XonXoffFlow = False
Inx_XonXoffFlow = False
ReplaceWhenParityError = False
IgnoreNullChar = False
RtsControl = RtsDisable
XonLimit = 500
XoffLimit = 500
ByteSize = _8
Parity = None
StopBits = _1
XonChar = #17
XoffChar = #19
ReplacedChar = #0
ReadIntervalTimeout = 10
ReadTotalTimeoutMultiplier = 0
ReadTotalTimeoutConstant = 0
WriteTotalTimeoutMultiplier = 0
WriteTotalTimeoutConstant = 0
OnReceiveData = Comm1ReceiveData
OnModemStateChange = Comm1ModemStateChange
Left = 400
Top = 88
end