前几天刚写了一个
下面是摘了主要的几个函数
你看看
稍作改动就可以用
type
TComm = Class(TThread)
protected
procedure Execute; override;
end;
Procedure TComm.Execute;
var
dwEvtmask, dwOvres, bb : Dword;
RXFinish : Bool;
begin
FreeOnTerminate := True;
while not Terminated {true} do
begin
DwEvtMask:=0;
RXFinish:=WaitCommEvent(hcom,dwevtmask,@LpolR); //等待串口事件EV_RXCHAR
if not RXFinish then //如果返回True,已立即完成,否则继续判断
if GetLastError()=ERROR_IO_PENDING then //正在接收数据
begin
bb:=WaitForSingleObject(LpolR.hEvent,20);//等待500ms
Case bb of
Wait_Object_0: RXFinish:=GetOverLappedResult(hcom,LpolR,dwOvRes,False);
//返回False,出错
Wait_TimeOut: RXFinish:=False;//定时溢出
else RXFinish:=False; //出错
end;
end else RXFinish:=False;
if RXFinish then
begin
if WaitForsingleobject(Post_Event,infinite)=Wait_Object_0 then //等待同步事件置位
begin
resetEvent(Post_Event); //同步事件复位
PostMessage(Form1.handle,WM_CommNotify,0,0); //发送消息
//这里触发串口接收事件
end;
end;
sleep(1);
end;
end;
Procedure TForm1.MsgComm(Var Msg:Tmessage); //接收数据
var
clear : boolean;
coms : TComStat;
cbNum, Cbread, lpErrors : Dword;
i, j, CheckSum : integer;
s : Array[0..7] of Byte;
str : String;
ScrolBar : TScrollStyle;
begin
clear := clearCommerror(hcom,lperrors,@Coms);
if clear then
begin
cbNum :=Coms.cbInQue; //获取接收缓冲区待接收字节数
ReadFile(hcom,s,cbnum,Cbread,@LpolR); //读串口
SetEvent(Post_Event); //同步事件置位
str := '';
for i := 0 to Cbread-1 do
begin
ArrRec
:= s;
str := str + IntToHex(ArrRec,2) + ' ';
end;
Memo2.Lines.Add(str);
sleep(2);
// 接收数据判断并响应
end;
end;
Function TForm1.WriteStr(StrArr : Array of Byte):Boolean; //发送数据
var
DwCharsWritten,DwResword;
BRes : boolean;
Len : Integer;
Begin
Len := Length(StrArr);
BRes:=False;
if hcom<>INVALID_HANDLE_VALUE then
begin
DwCharsWritten:=0;
BRes:=WriteFile(Hcom,StrArr,Len,
DwCharsWritten,LpolW); //返回True,数据立即发送完成
if not BRes then
begin
if GetLastError()=Error_IO_Pending then
begin //正在发送数据
DwRes:=WaitForSingleObject(LpolW^.hEvent,Infinite);
if DwRes=Wait_Object_0 then // 如果不相等,出错
BRes:=GetOverLappedResult(hcom,LpolW^,DwCharsWritten,False) //返回False,出错
else BRes:=true; //数据发送完成
end;
end;
end;
Result:=Bres;
end;
Procedure TForm1.CommInitialize;
Var
Lpdcb:TDCB;
Comm : Pchar;//String;
BoudRate : Cardinal;
begin
BoudRate := StrToInt(ComBoBox2.Text);
Comm := Pchar(ComBoBox1.Text);
hcom := createFile(Comm, //串口,可为com1-com4
generic_read or Generic_write,//访问模式
0, //共享模式,必须为0
nil, //安全属性指针
open_existing, ///找开方式必须为open_existing
File_Flag_Overlapped,//文件属性,本文设为交迭标志
0); //临时文件句柄,必须为0
if hcom<>invalid_Handle_Value then
begin
SetupComm(hcom,4096,4096); //设置缓冲区长度
getCommState(hcom,lpdcb); //设置串口
// BuildCommDCB('baud=BoudRate parity=N data=8 stop=1',Lpdcb);
lpdcb.BaudRate := BoudRate;
lpdcb.ByteSize := 8;
setCommState(hcom,lpdcb);
SetCommMask(Hcom,ev_Rxchar); //设置串口事件屏蔽
end else showMessage('无法打开串口!');
end;