首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > .NET >

帮忙看看:spcomm接收数据不及时导致数据不全有关问题

2013-07-16 
帮忙看看:spcomm接收数据不及时导致数据不全问题拉俩spcomm控件 分别创建俩个串口com1(本机),com2(usb ser

帮忙看看:spcomm接收数据不及时导致数据不全问题
拉俩spcomm控件 分别创建俩个串口com1(本机),com2(usb serial port) 参数设置:BaudRate 115200, Parity N无, ByteSize 8, StopBits 1
com1 定时5秒发给com2(5秒发完后停止发送) ,com2收到数据再发给com1(相当于全双工模式)我需要做的功能是,取com1发出的数据和com1接收的数据进行比较(包括Data和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个字节通过串口发送,的确不需要那么长的超时,一般这种就几毫秒到几十毫秒。

热点排行