procedure Outputgoon(); var StrData:string; begin StrData:='a'; StrtoASCII_and_Send(StrData); sleep(500); StrData:='b'; StrtoASCII_and_Send(StrData); sleep(500); StrData:='c'; StrtoASCII_and_Send(StrData); sleep(500); end;procedure StrtoASCII_and_Send(var x:string); begin StrtoASCII(x); senddata(x); end;procedure StrtoASCII(var x:string); var i,Len:byte; begin Len:=length(x)+2; setlength(sbuf,Len); for i:=0 to len-3 do begin sbuf[i]:=ord(x[i+1]); end; sbuf[i]:=$0D; i:=i+1; sbuf[i]:=$0A; end;procedure senddata(var x:string); var i:integer; commflg:boolean; begin viewstring:=''; commflg:=true; for i:=0 to length(x)+1 do begin if not Form1.comm1.writecommdata(@sbuf[i],1) then begin commflg:=false; break; end; viewstring:=viewstring+ inttohex(sbuf[i],2)+' '; end; viewstring:='发送'+ viewstring; Form1.memo1.lines.add(viewstring); Form1.memo1.lines.add(''); if not commflg then messagedlg('发送失败 !' ,mterror,[mbyes],0);end;
procedure Outputgoon(); var StrData:string; begin StrData:='a'; StrtoASCII_and_Send(StrData); sleep(500); StrData:='b'; StrtoASCII_and_Send(StrData); sleep(500); StrData:='c'; StrtoASCII_and_Send(StrData); sleep(500); end; StrData:='a';StrData:='b';StrData:='c';发送给下位机后,下位机会发回上位机数据; procedure Outputgoon();这个函数在我收到下位机数据后,再次发送;我循环就是用这个函数
主程序那么大量地Sleep,难怪反应慢!
to sy_100000 我想发送一次停500ms,所以要用到这么多sleep
嘿嘿,兄弟,把这一堆移到一个独立的线程就好了 还有不要用什么控件,直接用api就好了
Sleep不好在主线程里用的!
to qizhi_t 这一堆指我上面所有代码吗?这些代码是spcomm的写线程,不就是一个线程了吗? 关于改用api,我会试下..
to qizhi_t 谢谢你的回复,有点不明白,我的发送已经是写线程了,你指的自己写线程是指什么,能不能给点指导性代码
var
StrData:string;
begin
StrData:='a';
StrtoASCII_and_Send(StrData);
sleep(500);
StrData:='b';
StrtoASCII_and_Send(StrData);
sleep(500);
StrData:='c';
StrtoASCII_and_Send(StrData);
sleep(500);
end;procedure StrtoASCII_and_Send(var x:string);
begin
StrtoASCII(x);
senddata(x);
end;procedure StrtoASCII(var x:string);
var
i,Len:byte;
begin
Len:=length(x)+2;
setlength(sbuf,Len);
for i:=0 to len-3 do
begin
sbuf[i]:=ord(x[i+1]);
end;
sbuf[i]:=$0D;
i:=i+1;
sbuf[i]:=$0A;
end;procedure senddata(var x:string);
var
i:integer;
commflg:boolean;
begin
viewstring:='';
commflg:=true;
for i:=0 to length(x)+1 do
begin
if not Form1.comm1.writecommdata(@sbuf[i],1) then
begin
commflg:=false;
break;
end;
viewstring:=viewstring+ inttohex(sbuf[i],2)+' ';
end;
viewstring:='发送'+ viewstring; Form1.memo1.lines.add(viewstring); Form1.memo1.lines.add(''); if not commflg then messagedlg('发送失败 !' ,mterror,[mbyes],0);end;
var
StrData:string;
begin
StrData:='a';
StrtoASCII_and_Send(StrData);
sleep(500);
StrData:='b';
StrtoASCII_and_Send(StrData);
sleep(500);
StrData:='c';
StrtoASCII_and_Send(StrData);
sleep(500);
end; StrData:='a';StrData:='b';StrData:='c';发送给下位机后,下位机会发回上位机数据;
procedure Outputgoon();这个函数在我收到下位机数据后,再次发送;我循环就是用这个函数
我想发送一次停500ms,所以要用到这么多sleep
还有不要用什么控件,直接用api就好了
Sleep不好在主线程里用的!
这一堆指我上面所有代码吗?这些代码是spcomm的写线程,不就是一个线程了吗?
关于改用api,我会试下..
谢谢你的回复,有点不明白,我的发送已经是写线程了,你指的自己写线程是指什么,能不能给点指导性代码
二:循环的话最好不要用字符串类型,很耗CPU资源的,建议放在LIST流里,然后一次显示出来
一,程序改为自己写的延时函数后,按键无法响应问题解决.但是,但循环通信时,出现窗体无法关闭.
二,你所说的不要用字符串是什么意思,我没用字符串发送.
谢谢回复
该函数放到单独的线程中去发送,按钮中事件只要thread.resume即可。
你在主界面线程中sleep肯定要慢的
我把Outputgoon();放在单独线程中去了,现在按键有反应,但就是窗口在循环通信时不能关闭?这是为什么
while not MeterNextFlag do //等待本帧通讯结束
Application.ProcessMessages;
sleep(200);
用你的循环等待,窗口在循环通信时不能关闭的问题还不能解决
现在还有一个问题,就是当串口(用spcomm控件)循环通信时,关闭窗体的时候不能立即反应,得等5~10秒才能关闭.有人说把循环通信部分用线程循环,我试了一下还是一样.请问具体应该解决这个问题,最好给出详细代码,或者代码框架也行,多谢了...再次期待你的回复:)
现在还有一个问题,就是当串口(用spcomm控件)循环通信时,关闭窗体的时候不能立即反应,得等5~10秒才能关闭.有人说把循环通信部分用线程循环,我试了一下还是不行. 请问具体应该怎样解决这个问题,最好给出详细代码,或者代码框架也行,多谢了...
再次期待你的回复:)
可以用TIMER控件来代替SLEEP。
FTComm:=TComm.Create(nil);
FTComm.CommName := '\\.\'+sComName; //解决超过十的串口问题
FTComm.BaudRate := 4800;
FTComm.Inx_XonXoffFlow := False;
FTComm.Outx_XonXoffFlow := False;
FTComm.ReadIntervalTimeout := 220;
FTComm.StartComm; tmr_Send := TTimer.Create(nil);
tmr_Send.Enabled := False;
tmr_Send.OnTimer := OnTimerS;
tmr_SendNext := TTimer.Create(nil);
tmr_SendNext.Enabled := False;
tmr_SendNext.Interval := 550;
tmr_SendNext.OnTimer := IncSingSend;我这里用了好几个TTimer来解决定时发送的问题。
procedure ComSendMSG();virtual; abstract; //通过串口发送指令给探测器
procedure IncSingSend(Sender: TObject);virtual; abstract; //通过串口发送指令给探测器
procedure ComRevMSG(Sender: TObject; Buffer: Pointer;
BufferLength: Word);virtual;abstract;
public
FTClientDataSet: TClientDataSet; //用于在内在中存储各个探测器的值和状态 FTComm: TComm; //spcomm 串口类成
property FiSleep: Integer read iSleep write SetiSleep;
property FsComplete:string read sComplete write SetCompT;
property sBatchNO:string read FBatchNO write SetBatchNo;
property TypeName:string read FTypeName write SetTypeName;
constructor Create(sComName:String);virtual;
destructor Destroy; virtual;
procedure Start(aInters:Integer);virtual;
procedure Stop;
procedure Suspend;
procedure ReStart; virtual;基类中的部分代码,可以参考下