读书人

帮忙看看:spcomm接收数据不及时导致数

发布时间: 2013-07-16 22:38:05 作者: rapoo

帮忙看看:spcomm接收数据不及时导致数据不全问题
拉俩spcomm控件 分别创建俩个串口com1(本机),com2(usb serial port) 参数设置:BaudRate 115200, Parity N无, ByteSize 8, StopBits 1
com1 定时5秒发给com2(5秒发完后停止发送) ,com2收到数据再发给com1(相当于全双工模式)我需要做的功能是,取com1发出的数据和com1接收的数据进行比较(包—ata和length)如果一样则提示OK 不一样则提示Error
我现在碰到的问题是:由于接收数据时会有些数据来的比较缓慢,导致接收数据变少(虽然最后也能接收到),但是影响了接收的那个全局变量,导致俩边数据总是不一致,我知道是sleep一下,但不知道放在哪里,请指导下,谢谢
代码:


//自动发送5S事件
procedure TFrmMain.btnAutSendClick(Sender: TObject);
begin

if (not bOpenCom1) or (not bOpenCom2) then
begin
ShowMessage('请打开串口后再发送!');
Exit;
end;
if sMemsend.text='' then
begin
ShowMessage('请输入要发送的内容!');
Exit;
end;

if StartSend(5) then
begin
btnAutSend.Enabled:=False;//定时器
bAutoCountSend := True;//自动发送5S标记

end;


end;

function TFrmMain.StartSend(const Ltime: Cardinal): Boolean; // 读入要发送的时间长度并设定计时发送的起始时间和时间设置
begin
Result := False;

dtBegin := now;//开始计时
LsendTime := Ltime;


tmrAutoSend.Enabled := True;
tmrAutoSend.Interval:=10;

Result := True;
end;

//定时器
procedure TFrmMain.tmrAutoSendTimer(Sender: TObject);
var
i:Integer;
begin
try
if bAutoCountSend then
begin
i := SecondsBetween(now, dtBegin);
if Trunc(i) >= LSendtime then
begin
tmrAutoSend.Enabled := False;
btnAutSend.Enabled := True;
bAutoCountSend := False;

if (sendstr = gRecstr2)and(nsendData=gRecData2) then//sendstr,nsendata 分别是com1发出data和length,gRecstr2和gRecData2是接收的Data和length
begin


ShowMessage('Ok');
end
else
begin
ShowMessage('Error');
end;
end
else
if not SendData then
begin
bAutoCountSend := False;
tmrAutoSend.Enabled := False;
Exit;
end;

end;

except
on E:exception do
begin
bAutoCountSend := False;
tmrAutoSend.Enabled := False;
end;
end;

end;

function TFrmMain.senddata():boolean;
var
sErr,strSend:string;
i:Integer;
begin
result:=false;
try

if not bHexSend then
begin
if Comm1.WriteCommData(PChar(Trim(sMemSend.text)),Length(sMemSend.text)) then
begin
nsendData:=nsendData + Length(sMemSend.text);
sendstr:= sendstr + Trim(sMemSend.text);//保存对比
sLbSend.Caption:='发送:'+IntToStr(nsendData);
end
else
DosendError(Length(sMemSend.text));
end
result:=True;
except
on E :Exception do
begin
Result:=False;
sErr:='Send Data Error:'+E.Message;
SaveErrMsg(sErr);
sMemRec1.Lines.Add(sErr);
end;
end;

end;


[解决办法]
OnReceiveData 的第一句就是sleep()。更实用的在这儿判断接收缓冲区的接收到的数据长度,长度够了就不等待

[解决办法]
我也在用SPComm控件,谈谈我的建议吧!你使用以下方法试试:


1、
ReceiveData := false;
//Com1.SendData()

2、
for i := 1 to 500 do
begin
Delay(2);
inc(timeout);

if timeout >= 60 then //120毫秒未收到数据,认为超时
begin
m_Log.Error(Format('时已达120,未收到Com2回复', ));
Exit;
end;
end;

if ReceiveData := True then
begin
//do something
end;

3、

procedure Com1ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
var
nRBuffer:array of Byte;
begin
ReceiveData := True;
//do something
end;

//Delay函数原型
procedure Delay(msecs:integer);
var
FirstTickCount:longint;
begin
FirstTickCount:=GetTickCount;
repeat
Application.ProcessMessages;
until ((GetTickCount-FirstTickCount) >= Longint(msecs));
end;


另外,115个字节通过串口发送,的确不需要那么长的超时,一般这种就几毫秒到几十毫秒。

读书人网 >.NET

热点推荐