关于多线程串口通讯,肯请各位大侠帮忙!!!(100分)

S

seaoy

Unregistered / Unconfirmed
GUEST, unregistred user!
在线程中处理接收的数据花费的时间较长大概是1000-5000mS,请问怎么解决?
多谢各位!!!
请看以下代码:
TCommThread = Class(TThread)
private
Re:string;
protected
procedure Execute;override;
procedure Receive;
end;

procedure TCommthread.Execute ;
var
dwLength: DWORD;
i,j:integer;
TempByte: Byte;
FirstTickCount:longint;
Change:string;
ChangeV:real;
begin
Re:='';
freeonterminate:=true;
Form1.StatusBar1.Panels[0].Text :='Receiving...';
PurgeComm(CommHandle,(PURGE_RXABORT and PURGE_RXCLEAR and PURGE_TXCLEAR));
FirstTickCount:=GetTickCount;
repeat
Application.ProcessMessages;
DWLENGTH:= Form1.GetInCount;
IF DWLENGTH >0 then
begin
for i:=1 to dwLengthdo
begin
Form1.ReadData(@TempByte, 1);
re:=re+chr(tempbyte);
FORM1.Memo1.Text :=FORM1.Memo1.Text+' '+inttostr(tempbyte);
end;
end;
until (ORD(re[LENGTH(re)])=13) AND (LENGTH(re)>3);//((GetTickCount-FirstTickCount) >= 5100);
Form1.StatusBar1.Panels[2].Text:=inttostr(GetTickCount-FirstTickCount);
//************************************
FirstTickCount:=GetTickCount;
I:=3;
j:=0;
Change:='';
while I<=Length(Re)do
begin
if ord(re)=13 then
begin
inc(j);
if j<5 then
begin
ChangeV:=strtofloat(Change);
(Form1.GroupBox3.Controls[j-1] as Tedit).text:=currtostr(ChangeV*1000);
end
else
j:=0;
Change:='';
i:=I+3;
end;
Change:=change+re;
inc(i);
end;
// synchronize(Receive);
Form1.StatusBar1.Panels[1].Text:=inttostr(GetTickCount-FirstTickCount);
//****************************************这段须要1000-5000MS不等;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
post_event:=CreateEvent(nil,true,true,nil);
CommThread:=TCommThread.Create(false);
CommThread.Priority :=tpLower;
CommThread.Resume;
SENDSTR('QM 11');
end;

procedure TForm1.Commint(p:string;b:integer);
var
DCB:TDCB;
begin
CommHandle := CreateFile(pchar(p),GENERIC_READ,0,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL OR FILE_FLAG_OVERLAPPED, 0);
if CommHandle = INVALID_HANDLE_VALUE then
begin
Connected:=false;
Exit;
end;
setupcomm(CommHandle,4096,1024);
GetCommState(CommHandle,DCB);
DCB.BaudRate := b;
DCB.ByteSize := 8;
SetCommState(CommHandle, DCB);
setcommMask(CommHandle,ev_rxchar);
Connected:=true;
end;

procedure TForm1.SendStr(str: String);
var
i:integer;
begin
str := str+Chr(13);
for i:=1 to Length(str)do
TransmitCommChar(commhandle,str);
end;

function TForm1.GetInCount:longint;
var
dwErrorFlags :DWORD;
ComStat : TComStat;
begin
RESULT:=0;
PurgeComm(CommHandle,(PURGE_RXABORT and PURGE_RXCLEAR));
Clearcommerror(CommHandle,dwErrorFlags,@ComStat);
Result := COMSTAT.cbInQue;
end;

function TForm1.ReadData(pBuffer: PChar;
BufferSize: DWORD): boolean;
var
nRead: DWORD;
begin
Result := ReadFile(CommHandle, pBuffer^, BufferSize, nRead, Nil);
end;
 
你把比较慢的那些代码一个个去掉看看就知道哪里慢了。
另外,下面语句在线程中是很不安全的(应使用synchronize),极易引起错误,也
可能是速度慢的原因,应该立即删除或改写。(因为要访问VCL)
FORM1.Memo1.Text :=FORM1.Memo1.Text+' '+inttostr(tempbyte);
(Form1.GroupBox3.Controls[j-1] as Tedit).text:=currtostr(ChangeV*1000);
Form1.StatusBar1.Panels[1].Text:=inttostr(GetTickCount-FirstTickCount);
 
Huzzz:
FORM1.Memo1.Text :=FORM1.Memo1.Text+' '+inttostr(tempbyte);这只是用做调试,
下面的我用synchronize处理情况也一样。
(Form1.GroupBox3.Controls[j-1] as Tedit).text:=currtostr(ChangeV*1000);
Form1.StatusBar1.Panels[1].Text:=inttostr(GetTickCount-FirstTickCount);
 
我把这段代码放在主窗口中运行,只需要0个TICK。你自己试试吧。
procedure TForm1.Button1Click(Sender: TObject);
var
dwLength: DWORD;
i,j:integer;
TempByte: Byte;
FirstTickCount:dword;
Change:string;
ChangeV:real;
Re:string;
begin
Re:='Hwe;alfkal adlfkalsfk9aewr'#13'234.56'#13' nfkasdfj'#13'aopserjfalrenf'#13'kad jfuasidjfasd'#13;
//************************************
FirstTickCount:=GetTickCount;
I:=3;
j:=0;
Change:='';
while I<=Length(Re)do
begin
if ord(re)=13 then
begin
inc(j);
if j<5 then
begin
ChangeV:=strtofloatdef(Change,0);
(Form1.GroupBox3.Controls[j-1] as Tedit).text:=currtostr(ChangeV*1000);
end
else
j:=0;
Change:='';
i:=I+3;
end;
Change:=change+re;
inc(i);
end;
// synchronize(Receive);
Form1.StatusBar1.Panels[1].Text:=inttostr(GetTickCount-FirstTickCount);
//****************************************这段须要0MS;
end;
 
MEMO。TEXT赋值是最慢的。
因为每加一个字节都要先取出以前的。
再合并再放到MEMO中再刷新。
如果很我的话会越来越慢。
 
用assign.
 

Similar threads

顶部