串口通信,要同时接受ABC三相输入电压,其中数据接受方式为A1,B1,C1,A2,B2,C2....A1024,B1024,C1024.共1024*3=3072个数据,其中串口输入缓冲区大小设置为6144,但是运行结果报错“class EStackOverFlow With Message "Stack OverFlow".”
其中,我的程序如下: //处理控件中的该事件,获取底层交换数据和连线状态
procedure TForm5.MSComm1Comm(Sender: TObject);
var
  i,inputlen,tmpint:integer;
  tmpvar:variant;
begin
  
  if mscomm1.CommEvent=comevreceive then
  begin
    delay(100);
    inputlen:=mscomm1.InBufferCount;
    tmpvar:=mscomm1.Input;
    count:=count+inputlen;
    for i:=0 to inputlen-1 do
      begin
        tmpint:=tmpvar[i];
        index:=i+j;
        a[index]:=tmpint;
      end;
    j:=index+1;
  end;
end;//转换并存储数据
procedure TForm5.Button3Click(Sender: TObject);
var
k,x,i:integer;
jj:integer;begin
  max1:=-9999.0; max2:=-9999.0; max3:=-9999.0;
  s1:=0.0; s2:=0.0;s3:=0.0;s4:=0.0;s5:=0.0;s6:=0.0;
  s7:=0.0; s8:=0.0;s9:=0.0;s10:=0.0;s11:=0.0;s12:=0.0;
  memo1.Clear;memo2.Clear;memo3.clear;memo4.Clear;
  memo5.Clear;memo6.Clear;memo7.clear;memo8.Clear;
  memo9.Clear;memo10.Clear;memo11.clear;memo12.Clear;
  memo13.Clear;  jj:=0;
  for k:=0 to (count div 2)-1 do
  begin
   b[k]:=(a[jj]+256*a[jj+1]);
   jj:=jj+2;
   if b[k]<$8000 then
     begin
       b[k]:=b[k]/32768;
     end
   else
     begin
       b[k]:=(b[k]-65536)/32678;
     end;
  end;   //显示输入电压曲线
  if xuanze=1 then
  begin
      
      Fastlineseries1.Clear;Fastlineseries1.Clear;Fastlineseries1.Clear;
      i:=0;  x:=0;
      while(i<3072) do
      begin
                Fastlineseries1.AddXY(x*0.2,b[i],'',clred);
        
         Fastlineseries2.Addxy(x*0.2,b[i+1],'',clgreen);
        
        Fastlineseries3.Addxy(x*0.2,b[i+2],'',clblue);
        i:=i+3;
        x:=x+1;
      end;
      i:=0;
      while(i<3072) do
      begin
        s1:=s1+b[i];
        if max1<b[i] then
                  begin
                    max1:=b[i];
                  end;
        memo1.Lines.Add(floattostr(b[i]));
        memo1.lines.savetofile('A相输入电压.txt');
        i:=i+3;
      end;
    m1:=max1;
    v1:=max1/1.414;
    a1:=s1/1024;
    ComboBox2Change(Sender);      i:=1;
      while(i<6144) do
      begin
        s2:=s2+b[i];
        if max2<b[i] then
                  begin
                    max2:=b[i];
                  end;
        memo2.Lines.Add(floattostr(b[i]));
        memo2.lines.savetofile('B相输入电压.txt');
        i:=i+3;
      end;
    m2:=max2;
    v2:=max2/1.414;
    a2:=s2/1024;
    ComboBox3Change(Sender);      i:=2;
      while(i<3072) do
      begin
        s3:=s3+b[i];
        if max3<b[i] then
                  begin
                    max3:=b[i];
                  end;
        memo3.Lines.Add(floattostr(b[i]));
        memo3.lines.savetofile('C相输入电压.txt');
        i:=i+3;
      end;
    m3:=max3;
    v3:=max3/1.414;
    a3:=s3/1024;
    ComboBox4Change(Sender);
  end;end;请问各位大大,是否输入缓冲区设置过大,数据溢出,要如何处理?谢谢!希望知道的能指点一二,只要诚心回答的都有分,谢谢!

解决方案 »

  1.   

    Stack OverFlow一般是函数不小心反复互相调用了ComboBox4Change是不是会导致、自动触发Button3Click?
      

  2.   

    不好意思,我程序没有解释清楚,我的具体程序如下://处理控件中的该事件,获取底层交换数据和连线状态 
    procedure TForm5.MSComm1Comm(Sender: TObject); //转换并存储数据 
    procedure TForm5.Button3Click(Sender: TObject); ComboBox4Change(Sender); -----这个显示的是幅值,这个没关系,不用关注主要是这个地方出错了:
    //处理控件中的该事件,获取底层交换数据和连线状态 
    procedure TForm5.MSComm1Comm(Sender: TObject); 
    var 
      i,inputlen,tmpint:integer; 
      tmpvar:variant; 
    begin 
      
      if mscomm1.CommEvent=comevreceive then 
      begin 
        delay(100); 
        inputlen:=mscomm1.InBufferCount; 
        tmpvar:=mscomm1.Input; 
        count:=count+inputlen; 
        for i:=0 to inputlen-1 do 
          begin 
            tmpint:=tmpvar[i]; 
            index:=i+j; 
            a[index]:=tmpint; 
          end; 
        j:=index+1; 
      end; 
    end; 我将输入缓冲区设置为2048,接收转速数据1024时没有出错,可以正常显示,可是在显示三相电压时数据就有1024*3=3072个,因为串口按照高低字节接受,所以缓冲区应该为3072*2=6144,可是在运行接收电压数据程序就显示错误“class EStackOverFlow With Message "Stack OverFlow".” 
    所以,我想应该是输入缓冲区溢出?
      

  3.   

    可是我将输入缓冲区设置6144=1024*6,可是还是在运行接收电压数据程序就显示错误“class EStackOverFlow With Message "Stack OverFlow".” 
      

  4.   

    在ide运行一下,如果是堆栈溢出,会显示函数调用层次很深的
      

  5.   

    经过断点验证:出错的地方在下面的程序://处理控件中的该事件,获取底层交换数据和连线状态 
    procedure TForm5.MSComm1Comm(Sender: TObject); 
    var 
      i,inputlen,tmpint:integer; 
      tmpvar:variant; 
    begin 
      
      if mscomm1.CommEvent=comevreceive then 
      begin 
        delay(100); 
        inputlen:=mscomm1.InBufferCount; 
        tmpvar:=mscomm1.Input; 
        count:=count+inputlen; 
        for i:=0 to inputlen-1 do 
          begin 
            tmpint:=tmpvar[i]; 
            index:=i+j; 
            a[index]:=tmpint; 
          end; 
        j:=index+1; 
      end; 
    end;
    其中数组a,b的声明如下:
    public
        { Public declarations }
      a:array[0..20000] of integer;
        b:array[0..10000] of currency; 
    请问,究竟是哪里出错?请各位大大提供宝贵的意见!
      

  6.   

    是不是要修改project-options -linker-stack size 大小,默认大小是100K,将stack size 允许的最大值设置大点1M,恩,先试试
      

  7.   

    嗯,将串口输入缓冲区设置为8000,修改project-options -linker-max stack size 大小为1M,将
    procedure TForm5.MSComm1Comm(Sender: TObject); 
    中的延时函数改为delay(20),其中修改数组a,b的声明如下: 
    public 
        { Public declarations } 
      a:array[0..10000] of integer; 
        b:array[0..5000] of currency; 
    经过多次调试,终于修订为以上参数,运行通过,谢谢各位的支持与帮助!