问题描述:
        在我的delphi程序中用mscomm控件接受数据,经常数据出错!!但用comtools等串口调试工具接受下位机数据确没有任何问题,不知何故??是不是mscomm参数设置不对,还是我的oncomm事件写法有问题呢?????源代码如下:
    (1)     formcreate事件中对mscomm部分参数初始化:
         //初始化串口
   mscomm1.InBufferCount:=0;  //清空接收缓冲区
   mscomm1.OutBufferCount:=0;//请空发送缓冲区
   mscomm1.InputLen:=0;     //Input读取整个缓冲区的内容
   mscomm1.RThreshold:=1;  //每次接收到字符即产生oncomm事件
   mscomm1.InBufferSize:=512;
   mscomm1.PortOpen:=true;
       //     (2)   oncomm事件   procedure TForm1.MSComm1Comm(Sender: TObject);
var
  vtemp:array of byte;
  ovtmp:olevariant;
  ireceived:integer;
  btmp:byte;
  i:integer;
begin
  if mscomm1.CommEvent=2 then //发生‘接收事件’
  begin
    ireceived:=mscomm1.InBufferCount;
    ovtmp:=mscomm1.Input;
    vtemp:=ovtmp;
    for i:=1 to ireceived do
    begin
      btmp:=vtemp[i];
      if (in_index+1) mod maxsize<>out_index then  //maxsize 全局变量,值4096
      begin
        in_index:=(in_index+1) mod maxsize;
        rusb[in_index]:=vtemp[i];            //rusb[0..4095],全局数组,用于保存接受数据
      end;
    end;
  end;
end;

解决方案 »

  1.   

    ireceived:=mscomm1.InBufferCount;
    if ireceived>0 then //加个判断好的哦....
    ................
      

  2.   

    mscomm1.InBufferCount:=0;  //清空接收缓冲区
       mscomm1.OutBufferCount:=0;//请空发送缓冲区
    上面兩句應該有問題, 查查幫助是什麼意思先
      

  3.   

    对啊,在c++中是这样的,看清楚了:
    m_com.setcommPort(1);
    m_com.SetInBufferSize(1024);//要设置buffer.
    m_com.SetOutBufferSize(512);//同上,单位是byte
    if(!m_com.GetPortOpen()) //打开com
    {m_com.SetPortOpen(TRUE);
    m_com.SetInputMode(1); //二进制方式或字符方式
    m_com.SetSettings("9600,n,8,1");设置速率等
    m_com..SetRThreshold(1);//打开才能引发事件
    m_com..SetInputLen(0);
    }
    自己去烟酒.注意,GetInput返回的是宽字节的UNICODE.
      

  4.   

    多谢大家关注
    to aiirii(ari-爱的眼睛)
     这两句没有问题,用来清空所设的缓冲区。
    to denjackson(Harley)
      没有汉字
      

  5.   

    to  tigerii(tigerii) 
      有更好的解决办法么
      

  6.   

    to   denjackson(Harley) 
    加了判断条件了,参数设置也如你的从c++程序了,但依然是接受数据错误啊
      

  7.   

    直接使用API吧,这样就不会有错啊,很容易啊,真的,不去做就觉得难啊
      

  8.   

    to  oushengfen(逸帆) 
       API经验不足啊,指点一二??、
      

  9.   

    我delphi程序收到的数据为:CC CC CC CC 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 16 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 7F 7F 00 7F 7F 00 
    CC CC CC CC 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 7F 7F 00 7F 7F 00 
    CC CC CC CC 20 00 00 00 2A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 55 00 00 00 7F 7F 55 7F 30 55 
    CC CC CC CC 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 37 55 00 00 55 7F 7F 55 7F 7F 55 
    CC CC CC CC 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20 00 00 00 00 00 00 00 55 00 00 55 7F 7F 55 7F 7F 00 
    CC CC CC CC 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 30 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 55 00 00 00 7F 7F 55 7F 7F 55 
    CC CC CC CC 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 00 00 00 55 7F 7F 55 7F 7F 55 
    CC CC CC CC 30 00 00 00 00 00 00 00 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 55 7F 7F 55 7F 7F 00 
    CC CC CC CC 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 55 00 00 00 7F 7F 55 30 7F 55 
    CC CC CC CC 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 30 00 00 00 55 7F 7F 55 7F 7F 55 
    CC CC CC CC 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 35 00 00 00 00 00 00 00 00 00 55 00 00 55 7F 7F 55 7F 7F 00 
      

  10.   

    哥们 以字节接收的时候要这样:
    MsComm1.InputMode := ComInputModebinary;
    在你的FormCreate中加入这条语句
      

  11.   

    另外 接收数据的时候要看下位机的波特率、奇偶校验、数据位长度  老兄你的程序都是Mscomm默认的 9600,n,8,1  看你设对了没有。还有,看你要接收的东西那么多 如果是一发生‘接收事件’就去读串口 那接收到的东西肯定不全啊!
      

  12.   

    1、mscomm1.InputMode := 1
    2、   
      if mscomm1.CommEvent=2 then 
       begin
        sleep(20);                          //在这停一下看看
        ireceived:=mscomm1.InBufferCount;
      .
        .
        if (in_index+1) mod maxsize<>out_index then  // in_index 有没有初始化呀?
        begin
          in_index:=(in_index+1) mod maxsize;
          rusb[in_index]:=vtemp[i];            
        end;
        
      

  13.   

    怎么一转眼 suuare(督察) 都回了两次了,哈哈。
      

  14.   

    to suuare(督察) (
       说到点子上了,是数据太多了,但下位机这样已经发送了,这是我修改别人的程序,目的就是需要改正上位机接受数据过程
      

  15.   

    问题还没解决。。
    我的程序中4个cc头后的那个数据不正确,应该显示是59,用comtools工具收发到的是59!
    CC CC CC CC 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 46 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 55 7F 7F 00 7F 7F 55 
    CC CC CC CC 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 00 00 00 55 7F 7F 55 7F 7F 55 
    CC CC CC CC 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 02 00 00 02 00 00 02 00 00 02 00 00 55 00 00 55 7F 34 02 7F 7F 55 
    CC CC CC CC 00 00 00 02 00 00 02 00 00 02 00 00 02 00 00 02 00 00 02 00 00 02 00 00 02 00 00 02 00 00 02 00 00 02 00 00 02 00 00 55 00 00 02 00 00 55 7F 7F 55 7F 7F 55
      

  16.   

    我用一个线程取并显示rusb[]中数据,不知那里是不是用bug,代码如下:(代码要求:找到4个cc头就开始接受数据)大侠们帮我看看啊
    while mainthd do
      begin
        if in_index<>out_index then
          begin //begin out
            out_index:=(out_index+1) mod maxsize;
            if hnum<4 then
            begin //begin hum
              htemp:=rusb[out_index];
              if htemp=$cc then
                 hnum:=hnum+1
              else
                 hnum:=0;
            end //end hnum
            else
            begin //begin data
            Form1.Memo1.Text:=Form1.Memo1.Text+(IntToHex(rusb[out_index],2))+' ';
           。
      

  17.   

    我设置的inbuffersize为1024,但oncomm事件中的ireceived变量值却大于1024!是溢出么?
      

  18.   

    我看你最开始设置的不是每收到一个字符就产生事件吗,可以在MSComm1Comm中把收到的数据也
    IntToHex 出来,看看是不是59
      

  19.   

    修改后的oncomm事件:
    procedure TForm1.MSComm1Comm(Sender: TObject);
    var
      vtemp:array of byte;
      ovtmp:olevariant;
      ireceived:integer;
      viewstring:string;
      i:integer;
    begin
      viewstring:='';
      if mscomm1.CommEvent=2 then //发生‘接收事件’
      begin
        sleep(20);
        ireceived:=mscomm1.InBufferCount;
        if ireceived>0 then
        begin
        ovtmp:=mscomm1.Input;
        vtemp:=ovtmp;
        for i:=1 to ireceived do
        begin
          if (in_index+1) mod maxsize<>out_index then
          begin
            in_index:=(in_index+1) mod maxsize;
            rusb[in_index]:=vtemp[i];
            viewstring:=viewstring+inttohex(rusb[in_index],2)+' ';
          end;
        end;
        viewstring:=viewstring+'$13'+'****'+'$13'+IntToStr(ireceived)+'*'+IntToStr(Mscomm1.InBufferSize);
        Memo1.Lines.Add(viewstring);
        //mscomm1.InBufferCount:=0;
        end;  //ireceived>0
      end;
    end;
      

  20.   

    结果输出:
    Memo1
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 00 00 00 55 7F 7F 55 7F 7F 55 CC CC CC CC 59 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 55 7F 7F 55 7F 7F 00 CC CC CC CC 59 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 55 00 00 55 7F 7F 00 7F 7F 55 CC CC CC CC 59 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 00 00 00 55 7F 7F 55 7F 7F 55 CC CC CC CC 59 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 55 7F AF 55 16 28 00 CC CC CC CC 59 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 7F 7F 00 7F 7F 00 CC CC CC CC 59 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 7F 7F 00 7F 7F 00 CC CC CC CC 59 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 7F 7F 00 7F 7F 55 CC CC CC CC 59 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 55 7F 7F 00 7F 7F 55 CC CC CC CC 59 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 55 00 00 00 7F 7F 55 7F 7F 55 CC CC CC CC 59 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 55 7F 7F 55 7F 7F 55 CC CC CC CC 59 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 55 7F 7F 00 7F 7F 55 CC CC CC CC 59 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 55 00 00 00 7F 7F 55 7F 7F 55 CC CC CC CC 59 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 55 7F 7F 55 7F 7F 55 CC CC CC CC 59 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 55 7F 7F 00 7F 7F 55 CC CC CC CC 59 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 55 00 00 00 7F 7F 55 7F 7F 55 CC CC CC CC 59 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 55 7F 7F 55 7F 7F 55 CC CC CC CC 59 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 55 7F 7F 00 7F 7F 55 CC CC CC CC 59 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 55 00 00 00 7F 7F 55 7F 7F 55 CC CC CC CC 59 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 55 7F 7F 55 7F 7F 55 CC CC CC CC 59 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 55 7F 7F 00 7F 7F 55 CC CC CC CC 59 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 00 00 00 55 7F 7F 55 7F 7F 55 CC CC CC CC 59 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 55 7F 7F 55 7F 7F 55 CC CC CC CC 59 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 55 7F 7F 00 7F 7F 55 CC CC CC CC 59 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 55 00 00 00 7F 7F 55 7F 7F 55 CC CC CC CC 59 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 55 7F 7F 55 7F 7F 55 CC CC CC CC 59 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 55 7F 7F 00 7F 7F 55 CC CC CC CC 59 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 00 00 00 55 7F 7F 55 7F 7F 55 CC CC CC CC 59 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 55 7F 7F 55 7F 7F 55 CC CC CC CC 00 $13****$131610*2048
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 55 7F 7F 00 7F 7F 55 CC CC CC CC B6 $13****$1356*2048
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 00 00 00 55 7F 7F 55 7F 7F 55 CC CC CC CC B6 $13****$1356*2048
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 55 7F 7F 55 7F 7F 55 CC CC CC CC B6 $13****$1356*2048
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 55 7F 7F 00 7F 7F 55 CC CC CC CC B6 $13****$1356*2048
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 00 00 00 00 00 55 7F 7F 55 7F 7F 55 CC CC CC CC B6
      

  21.   

    第一振数据较正常,4个cc头后大部分都是59,但在该帧结束的时候有个错数!
    我的inbuffersize设为了2048,
      

  22.   

    还没有解决???
    把你的接收程序改成这样!
    procedure TForm1.MSComm1Comm(Sender: TObject);
    var a: array of byte;
        i, j: Word;
        vTmp: variant;
        ovTmp: olevariant;
        s: String;
    begin
      if Mscomm1.CommEvent = 2 then
       begin     Sleep(200);
         j := Mscomm1.InBufferCount;
         SetLength(a,j);
         ovTmp := Mscomm1.Input;
         vtmp := VarArrayCreate([0,j],varByte);
         vtmp := ovTmp;
         for i := 0 to j - 1 do
           a[i] := vtmp[i];
         S := '';
         for i := 0 to j - 1 do
           S := S + IntToHex(a[i],2) + ' ';
         Memo1.Lines.Add(S);
       end;end;
      

  23.   

    我查了下,是inbuffercount参数问题。当我把inbuffersize初始化为1024时,第一次发生oncomm事件时inbuffercount为1600左右,但以后每次oncomm事件都是56个字节,这个56非常特殊,它就是我我要的一帧数据的长度,
      

  24.   

    bang帮帮忙,大侠们
    (1) 为什么第一次oncomm事件的inbuffercount大于inbuffersize值
    (2) 既然缓冲溢出,那为什么第一次的收发的数据基本上却都正确 
    (3) 为什么以后的每次的oncomm事件的inbuffercount值都非常小,而且数据却部分是错的,特别是紧跟在4个cc头后的哪个数据
      (4)为什么没人帮帮我啊
      

  25.   

    inbuffercount小了你就改大点啊
    把延时时间再改长点试试
      

  26.   

    inbuffercount是系统值,不能自定义吧?
    延时长了没用,而且第一次的inbuffercount的值还加大了,达到4000多
      

  27.   

    发送和接收的com设置是否一致啊.你的接收com设置要和发送速率等一致.
    delphi平台下没开发过啊,我是这几天才学习delphi的,
    随便问一句,如何在tbutton控件里加入我的成员函数然后继承给我下次使用,实在不想
    加个button又写同样的代码,好烦啊.
      

  28.   

    inbuffercount值就是缓冲区中待接受的字节数啊,第一次值太大,显然我设的缓冲溢出了啊,但收到的数据好像还比较正常
    inbuffercount以后的值又非常小,只有56左右
    小其实没什么,我有数组存储它们,但发上来的数据却不正常了,怎么回事啊
    大侠我呼唤你
      

  29.   

    to denjackson(Harley;
    button1(sender);
      

  30.   

    你好好检查一下  这样写应该没有问题  用此方法我完成了2M以上文件的传输  还是不行你用SPCOMM控件试试
      

  31.   

    suuare(督察) 
    那个inbuffercount不正常啊
      

  32.   

    怎么都想不通为什么会设置了inbuffersize:=1024,第一次的inbuffercount却比1024大!
      

  33.   

    问题搞定了,谢谢大家了,尤其感谢suuare(督察) ;
     问题出在oncomm事件中循环语句 for i:=1 to ireceived do,应该是
       for i := 0 to j - 1 do,零下标开始,inbuffercount-1结束
      

  34.   

    哈哈,贺喜楼主。
    suuare(督察) 在这方面确实有一套,我上次的问题就是他帮忙搞定的。