T
TENTODBV
Unregistered / Unconfirmed
GUEST, unregistred user!
在我写的一个用MSComm控件实现与仪表通讯的程序中,MSComm控件的OnComm事件过程框架代码如下:
procedure TfrmMain.MSCommComm(Sender: TObject);
var
i,InputLen:integer;
UpperCaseBuff:string;
begin
if MSComm.CommEvent=ComEvReceive then
begin
sleep(300);
InputLen:=MSComm.InBufferCount;
InputString:=MSComm.Input;
i:=1;
while i<=InputLen do
begin
......省略部分代码
if InputString=#4 then //EOT
begin
UpperCaseBuff:=UpperCase(Buff);
RichEdit1.Text:=Buff;//全局变量,这个就是我想得到的结果
bOK:=true;//全局变量
exit;
end;
end;
end;
//发送命令按钮的代码框架如下:
procedure TfrmMain.Button2Click(Sender: TObject);
var
Sample,Cycle:integer;
tempstr:string;
begin
bGet:=true;
SLTest:=TStringList.Create;
Len:=0;
Count:=0;
Buff:='';
bOK:=false;
LinkString:='';
with frmMain.MSComm do
begin
if not PortOpen then
begin
CommPort:=ComNum;
Settings:=ComSetting;
PortOpen:=true;
end;
SendCommand('test ?');
//Timer1.Enabled:=false;//启动定时器定时刷新显示
end;
Sleep(2000);
ShowMessage(RichEdit1.Text);
//返回结果处理代码段
if bOK then
begin
//SLTest.Text:=Buff;
SLTest.Text:=RichEdit1.Text;
if SLTest.Count>0 then
begin
tempstr:=SLTest[0];
tempstr:=AnsiReplaceStr(tempstr,' ','');
tempstr:=AnsiReplaceStr(tempstr,'=','');
tempstr:=AnsiReplaceStr(tempstr,'SAMPLE','');
Sample:=StrToInt(tempstr);
Edit2.Text:=IntToStr(Sample);
end;
end;
end;
以上代码SendCommand('test ?');是通过串口发送命令给仪表,然后仪表会返回字符串值到全局变量Buff
问题是:如果没有前面所示的返回结果处理代码段
if bOK then
begin
......
end;
结果Buff确实是可以正确返回到RichEdit1框显示的。我加上返回结果处理代码段的目的是为了确定在已经接收到返回值时,对接收结果字符串进行处理。调试状态下,在MSCommComm中跟踪显示Buff值正确,bOK为true。按理来说执行返回结果处理代码段时,全局变量bOK值应该为true,且RichEdit1.Text的值不为空才对。
可是实际跟踪发现,执行到if bOK then时 bOK值总是是false,可是调试状态下,在MSCommComm中跟踪显示Buff值正确,bOK也已经是true了呀。bOK和Buff都是全局变量。
后来我又在返回结果处理代码段之前加上延时和显示代码
Sleep(2000);
ShowMessage(RichEdit1.Text);
明显看出无论延时多长时间,总是先显示ShowMessage(RichEdit1.Text);的空白结果然后RichEdit1才接收到返回字符串。
请问问题出在哪里?
procedure TfrmMain.MSCommComm(Sender: TObject);
var
i,InputLen:integer;
UpperCaseBuff:string;
begin
if MSComm.CommEvent=ComEvReceive then
begin
sleep(300);
InputLen:=MSComm.InBufferCount;
InputString:=MSComm.Input;
i:=1;
while i<=InputLen do
begin
......省略部分代码
if InputString=#4 then //EOT
begin
UpperCaseBuff:=UpperCase(Buff);
RichEdit1.Text:=Buff;//全局变量,这个就是我想得到的结果
bOK:=true;//全局变量
exit;
end;
end;
end;
//发送命令按钮的代码框架如下:
procedure TfrmMain.Button2Click(Sender: TObject);
var
Sample,Cycle:integer;
tempstr:string;
begin
bGet:=true;
SLTest:=TStringList.Create;
Len:=0;
Count:=0;
Buff:='';
bOK:=false;
LinkString:='';
with frmMain.MSComm do
begin
if not PortOpen then
begin
CommPort:=ComNum;
Settings:=ComSetting;
PortOpen:=true;
end;
SendCommand('test ?');
//Timer1.Enabled:=false;//启动定时器定时刷新显示
end;
Sleep(2000);
ShowMessage(RichEdit1.Text);
//返回结果处理代码段
if bOK then
begin
//SLTest.Text:=Buff;
SLTest.Text:=RichEdit1.Text;
if SLTest.Count>0 then
begin
tempstr:=SLTest[0];
tempstr:=AnsiReplaceStr(tempstr,' ','');
tempstr:=AnsiReplaceStr(tempstr,'=','');
tempstr:=AnsiReplaceStr(tempstr,'SAMPLE','');
Sample:=StrToInt(tempstr);
Edit2.Text:=IntToStr(Sample);
end;
end;
end;
以上代码SendCommand('test ?');是通过串口发送命令给仪表,然后仪表会返回字符串值到全局变量Buff
问题是:如果没有前面所示的返回结果处理代码段
if bOK then
begin
......
end;
结果Buff确实是可以正确返回到RichEdit1框显示的。我加上返回结果处理代码段的目的是为了确定在已经接收到返回值时,对接收结果字符串进行处理。调试状态下,在MSCommComm中跟踪显示Buff值正确,bOK为true。按理来说执行返回结果处理代码段时,全局变量bOK值应该为true,且RichEdit1.Text的值不为空才对。
可是实际跟踪发现,执行到if bOK then时 bOK值总是是false,可是调试状态下,在MSCommComm中跟踪显示Buff值正确,bOK也已经是true了呀。bOK和Buff都是全局变量。
后来我又在返回结果处理代码段之前加上延时和显示代码
Sleep(2000);
ShowMessage(RichEdit1.Text);
明显看出无论延时多长时间,总是先显示ShowMessage(RichEdit1.Text);的空白结果然后RichEdit1才接收到返回字符串。
请问问题出在哪里?