帮忙看看: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个字节通过串口发送,的确不需要那么长的超时,一般这种就几毫秒到几十毫秒。