程序自动退出的问题,各位高手帮小弟看看!

时间:2021-07-26 15:54:03
一个车辆无线管理系统的上位机程序,总是运行一段时间就不停的弹出警告窗口,弹出一定数量后程序自动退出。
程序在运行过程中接收串口的数据,进行处理,然后在不同的监控界面显示,同时写入数据库,现在我怀疑是写数据库出的问题,
下面把部分代码贴出来,大家帮看看是哪个地方的毛病。
写数据库
procedure TfrmGarageManageMain.IsEventOccur;  //处理数据,判断是否车在车库,是否有人进入,是否有火警
var
   i:integer;
   strSQL:string;
   strCarNo:string;
begin

   //判断车辆进出情况
   for i:=1 to iGarageCount do begin
      if (CarTime='全天') or ((CarTime='检查时间') and ((formatdatetime('hh:mm',time)>=CarTime1) and (formatdatetime('hh:mm',time)<=CarTime2)) or ((CarTime='停止时间') and ((formatdatetime('hh:mm',time)<=CarTime1) or (formatdatetime('hh:mm',time)>=CarTime2)))) then begin
         //打开插入数据的Query
         strSQL:='select top 1 * from hwjy_CarInout where PLACE='''+GaragePlace+'''';
         with Q do begin
            Close;
            SQL.Clear;
            SQL.Add(strSQL);
            Open;
         end;
         //查询车牌号
         strSQL:='select * from HWJY_GARAGE where GARAGE_NO='+inttostr(i)+' and POSITION_NO=1'
                  +' and PLACE='''+GaragePlace+'''';
         with QQ do begin
            Close;
            SQL.Clear;
            SQL.Add(strSQL);
            Open;
         end;
         if QQ.RecordCount=0 then begin
            strCarNo:='无牌照';
         end else begin
            strCarNo:=trim(QQ.Fieldbyname('CAR_NO').AsString);
         end;
         //1#车位有车进入
         if (Car1LBResultOld[i]=0) and (Car1LBResult[i]=1) then begin
            //写入数据库
                 MemoSerial.Lines.Add('第'+inttostr(i)+'车库1#车入库');
                 MemoSerial.lines.add('***********');
             with Q do begin
                Append;
                FieldByName('CAR_NO').AsString:=strCarNo;
                FieldByName('GARAGE_NO').AsString:=inttostr(i);
                FieldByName('POSITION_NO').AsString:='1';
                FieldByName('IOTIME').AsDateTime:=now;
                FieldByName('IOTYPE').AsString:='入库';
                FieldByName('PLACE').AsString:=GaragePlace;
                Post;
             end;
         end;
         //1#车位有车离开
         if (Car1LBResultOld[i]=1) and (Car1LBResult[i]=0) then begin
                 MemoSerial.Lines.Add('第'+inttostr(i)+'车库1#车出库');
                 MemoSerial.lines.add('******1*****');
             //写入数据库
             with Q do begin
                Append;
                FieldByName('CAR_NO').AsString:=strCarNo;
                FieldByName('GARAGE_NO').AsString:=inttostr(i);
                FieldByName('POSITION_NO').AsString:='1';
                FieldByName('IOTIME').AsDateTime:=now;
                FieldByName('IOTYPE').AsString:='出库';
                FieldByName('PLACE').AsString:=GaragePlace;
                Post;
             end;
         end;
         //查询车牌号
         strSQL:='select * from HWJY_GARAGE where GARAGE_NO='+inttostr(i)+' and POSITION_NO=2'
                  +' and PLACE='''+GaragePlace+'''';
         with QQ do begin
            Close;
            SQL.Clear;
            SQL.Add(strSQL);
            Open;
         end;
         if QQ.RecordCount=0 then begin
            strCarNo:='无牌照';
         end else begin
            strCarNo:=trim(QQ.Fieldbyname('CAR_NO').AsString);
         end;
         //2#车位有车进入
         if (Car2LBResultOld[i]=0) and (Car2LBResult[i]=1) then begin
                 MemoSerial.Lines.Add('第'+inttostr(i)+'车库2#车入库');
                 MemoSerial.lines.add('***********');
             //写入数据库
             with Q do begin
                Append;
                FieldByName('CAR_NO').AsString:=strCarNo;
                FieldByName('GARAGE_NO').AsString:=inttostr(i);
                FieldByName('POSITION_NO').AsString:='2';
                FieldByName('IOTIME').AsDateTime:=now;
                FieldByName('IOTYPE').AsString:='入库';
                FieldByName('PLACE').AsString:=GaragePlace;
                Post;
             end;
         end;
         //2#车位有车离开
         if (Car2LBResultOld[i]=1) and (Car2LBResult[i]=0) then begin
                 MemoSerial.Lines.Add('第'+inttostr(i)+'车库2#车出库');
                 MemoSerial.lines.add('***********');
            //写入数据库
             with Q do begin
                Append;
                FieldByName('CAR_NO').AsString:=strCarNo;
                FieldByName('GARAGE_NO').AsString:=inttostr(i);
                FieldByName('POSITION_NO').AsString:='2';
                FieldByName('IOTIME').AsDateTime:=now;
                FieldByName('IOTYPE').AsString:='出库';
                FieldByName('PLACE').AsString:=GaragePlace;
                Post;
             end;
         end;
      end;
   end;
end;


以下是弹出过的警告窗口信息
1.Access violation at address 07F43007 in module 'BORdbk70.dll',Read of address 08E50000.
2.Timed out waitting for process to terminate
3.Debugger fatal error during process reset:'Debug process is already running'.Please save your work and restar Delphi.
 上面的是在DELPHI下运行程序出现的
4.Access violation at address 00402F4F in module 'Pgaragemanage.exe'Read of address FFFFF9FF
 上面的是直接运行程序出现的,隔半秒不停的弹出,最后程序退出
查了一些资料,大部分说是内存泄漏问题,请问怎么解决呢?上火啊

15 个解决方案

#1


写数据库另一部分
////////////////////////////////////////////////////////////////////////////////
procedure TfrmGarageManageMain.IsEventOccurMan;  //处理数据,是否有人进入
var
   i:integer;
   h,m,s,mi:word;
   strSQL:string;
begin
   
      //判断人进入情况
      if (ManTime='全天') or ((ManTime='检查时间') and ((formatdatetime('hh:mm',time)>=ManTime1) and (formatdatetime('hh:mm',time)<=ManTime2))  or ((ManTime='停止时间') and ((formatdatetime('hh:mm',time)<=ManTime1) or (formatdatetime('hh:mm',time)>=ManTime2)))) then begin
             //提取数据库,判断是否有记录,并且已经超过了检查间隔时间
             decodetime(now-manLastTime,h,m,s,mi);
             if (h*3600+m*60+s>=manInterval) then begin
               for i:=1 to iGarageCount do begin
                  if ManLBResult[i]=1 then begin
                  //写入数据库
                  strSQL:='select top 1 * from hwjy_ManInout where PLACE='''+GaragePlace+'''';
                  with Q do begin
                     Close;
                     SQL.Clear;
                     SQL.Add(strSQL);
                     Open;
                  end;
                  with Q do begin
                     Append;
                     FieldByName('GARAGE_NO').AsString:=inttostr(i);
                     FieldByName('INTIME').AsDateTime:=now;
                     FieldByName('PLACE').AsString:=GaragePlace;
                     Post;
                  end;
                  ManLastTime:=now;
                  //声音报警
                  PlayWav(Pchar(nWavPath),Pchar('37.wav'),false);
               end;
         end;
      end;//判断有人进入情况
    end;
end;

////////////////////////////////////////////////////////////////////////////////
procedure TfrmGarageManageMain.IsEventOccurFire;  //处理数据,是否有火警
var
   i:integer;
   strSQL:string;
   h,m,s,mi:word;
begin
     //是否启动判断火灾情况
    if (FireTime='全天') or ((FireTime='检查时间') and ((formatdatetime('hh:mm',time)>=FireTime1) and (formatdatetime('hh:mm',time)<=FireTime2)) or ((FireTime='停止时间') and ((formatdatetime('hh:mm',time)<=FireTime1) or (formatdatetime('hh:mm',time)>=FireTime2)))) then begin
        for i:=1 to iGarageCount do begin
         //发生火灾
        if fire[i]>=35 then begin
               //声音报警
             PlayWav(Pchar(nWavPath),Pchar('fire.WAV'),false);
         end;
         end;
        //提取数据库,判断是否有记录,并且已经超过了检查间隔时间
       decodetime(now-FireLastTime,h,m,s,mi);
       if (h*3600+m*60+s>=FireInterval*1) then begin
          FireLastTime:=now;
          for i:=1 to iGarageCount do begin
              //写入数据库
                strSQL:='select top 1 * from hwjy_fire where PLACE='''+GaragePlace+'''';
                with Q do begin
                   Close;
                   SQL.Clear;
                   SQL.Add(strSQL);
                   Open;
                end;
                with Q do begin
                   Append;
                   FieldByName('GARAGE_NO').AsString:=inttostr(i);
                   FieldByName('FIRETIME').AsDateTime:=now;
                   FieldByName('PLACE').AsString:=GaragePlace;
                    if (fireFlag[i]=1) then begin
                     FieldByName('temperature').AsString:='-'+inttostr(fire[i]);
                   end else begin
                     FieldByName('temperature').AsString:=inttostr(fire[i]);
                   end;
                   if fire[i]>=35 then begin
                     FieldByName('type').AsString:='异常';
                   end else begin
                     FieldByName('type').AsString:='未见异常';
                   end;
                   Post;
                end;
             end;
         end;
      end; //判断火灾情况
end;


#2


定时器部分
procedure TfrmGarageManageMain.TimerWriteDataTimer(Sender: TObject);
begin
   ComputeLoop;
   if GarageTurnCount>1 then begin
      comm1.WriteCommData(pAnsiChar(commWriteData[intTurn]),length(commWriteData[intTurn]));
      sleep(20);
      MemoSerial.Lines.Add('车库在第 '+pAnsiChar(inttostr(intTurn)+' 排'));
      MemoSerial.lines.add('');
      intTurn:=intTurn+1;
      if intTurn>GarageTurnCount then intTurn:=1;
   end;
end;



串口接收数据并处理
procedure TfrmGarageManageMain.Comm1ReceiveData(Sender: TObject;
  Buffer: Pointer; BufferLength: Word);
var
   i,iGarageNum,iGarageNum1,iGarageNum2,iGarageNum3,b6,b5,b4,b3,b2,b1,b0,WD,RES1:integer;
   bytTemp:byte;
   tempTime,strSQL:string;
begin
    try
       Receivestring:='';
       Move(Buffer^,pchar(@ReceiveData)^,BufferLength);//接收数据
      for i:=1 to BufferLength do
      begin
          Receivestring:=Receivestring+inttohex(ReceiveData[i],2)+' ';
      end;
        MemoSerial.Lines.Add(Receivestring);
        MemoSerial.lines.add('');
       if (RightStr(inttohex(ReceiveData[1]+ReceiveData[4],1),2))<>inttohex(ReceiveData[5],1) then begin
          tempTime:='有错误发生'+DateTimeToStr(now);
          MemoSerial.Lines.Add(tempTime);
          MemoSerial.lines.add('');
          exit;
        end;
        iGarageNum:=ReceiveData[1]-20;
        car1[iGarageNum]:=(ReceiveData[2] and $80) div $80;
        car2[iGarageNum]:=(ReceiveData[2] and $40) div $40;
        man[iGarageNum]:=(ReceiveData[2] and $08) div $08;
        
        //此处零下温度判断,1为零下,0为零上
        IF (((ReceiveData[3] and $F8) div $F8)=1) then begin
          fireFlag[iGarageNum]:=1;

          b6:=(ReceiveData[3] and $04) div $04;
          if b6=1
          then b6:=0
          else b6:=1;
          b5:=(ReceiveData[3] and $02) div $02;
          if b5=1
          then b5:=0
          else b5:=1;
          b4:=(ReceiveData[3] and $01) div $01;
          if b4=1
          then b4:=0
          else b4:=1;
          b3:=(ReceiveData[4] and $08) div $08;
          if b3=1
          then b3:=0
          else b3:=1;
          b2:=(ReceiveData[4] and $04) div $04;
          if b2=1
          then b2:=0
          else b2:=1;
          b1:=(ReceiveData[4] and $02) div $02;
          if b1=1
          then b1:=0
          else b1:=1;
          b0:=(ReceiveData[4] and $01) div $01;
          if b0=1
          then b0:=0
          else b0:=1;

          RES1:=b6*64+b5*32+b4*16+b3*8+b2*4+b1*2+b0;
          WD:=RES1+1;

          fire[iGarageNum]:=WD;
        end else begin
          fireFlag[iGarageNum]:=0;
          fire[iGarageNum]:=ReceiveData[3]*16+ReceiveData[4]*1;
        end;
        car1Power[iGarageNum]:=(ReceiveData[2] and $20) div $20;
        car2Power[iGarageNum]:=(ReceiveData[2] and $10) div $10;
        if car1Power[iGarageNum]=1 then begin
               with QLog do begin
                  Append;
                  FieldByName('ERRORINFO').AsString:='第 '+inttostr(iGarageNum)+ ' 号车库中1#车辆发生掉电!';
                  FieldByName('TIME').AsDateTime:=now;
                  FieldByName('PLACE').AsString:=GaragePlace;
                  Post;
              end;
        end;
        if car2Power[iGarageNum]=1 then begin
               with QLog do begin
                  Append;
                  FieldByName('ERRORINFO').AsString:='第 '+inttostr(iGarageNum)+ ' 号车库中2#车辆发生掉电!';
                  FieldByName('TIME').AsDateTime:=now;
                  FieldByName('PLACE').AsString:=GaragePlace;
                  Post;
              end;
        end;
         DealwithData; //调用不加滤波的串口处理函数
    except
       exit;
    end;
end;

#3


串口处理后的数据进行滤波
procedure TfrmGarageManageMain.DealWithData;  //串口数据判断,取值为0或者1    0代表不存在事件,1代表存在事件
var
   i:integer;
begin
       //分别滤波,车辆开始滤波
     if LBCount<=LBTimes then begin
       for i:=loopStart to loopEnd do begin
          Car1Count[i]:=Car1Count[i]+car1[i];
          Car2Count[i]:=Car2Count[i]+car2[i];
       end;
     end else begin
         for i:=1 to iGarageCount do begin
         //保存上一次滤波结果
         Car1LBResultOld[i]:=Car1LBResult[i];
         Car2LBResultOld[i]:=Car2LBResult[i];
         //得出本次滤波结果
         if (Car1Count[i]/LBTimes)>LBJunZhi then begin
            Car1LBResult[i]:=1;
            Car1LBResultReal[i]:=1;
         end else begin
            Car1LBResult[i]:=0;
            Car1LBResultReal[i]:=0;
         end;
         if (Car2Count[i]/LBTimes)>LBJunZhi then begin
            Car2LBResult[i]:=1;
            Car2LBResultReal[i]:=1;
         end else begin
            Car2LBResult[i]:=0;
            Car2LBResultReal[i]:=0;
         end;
         Car1Count[i]:=0;
         Car2Count[i]:=0;
      end;
      LBCount:=0;
      IsEventOccur;
     end;


   //人数据情况
      for i:=1 to iGarageCount do begin
          //保存上一次结果
          ManLBResultOld[i] :=ManLBResult[i];
          //得出本次结果
          if man[i]=1 then begin
             ManLBResult[i]:=1;
          end else begin
             ManLBResult[i]:=0;
          end;
      end;
      IsEventOccurMan;
      //火灾数据情况
      IsEventOccurFire;

end;

#4



定时器部分
procedure TfrmGarageManageMain.TimerWriteDataTimer(Sender: TObject);
begin
//----------------------------------------------------------------
进入定时器后应该要执行Timer.Enabled := False;
   ComputeLoop;    if GarageTurnCount>1 then begin
      comm1.WriteCommData(pAnsiChar(commWriteData[intTurn]),length(commWriteData[intTurn]));
      sleep(20);
      MemoSerial.Lines.Add('车库在第 '+pAnsiChar(inttostr(intTurn)+' 排'));
      MemoSerial.lines.add('');
      intTurn:=intTurn+1;
      if intTurn>GarageTurnCount then intTurn:=1;
   end;
//----------------------------------------------------------------
退出时定时器后应该要执行Timer.Enabled := True;

end;

#5


错误信息?

#6


太长了,头晕...........

#7


错误信息在第一个帖子的最下面了,都是警告信息,程序运行一段时间后自动退出!

#8


感觉问题很有可能出在串口接收或写数据库的过程中!

#9


我也是做上位机的,但看了你的代码头大。。。
结构不清晰,程序没有分模块,程序中的常量随处可见,一团糟。。。

建议,将接收模块、控制模块、数据解析、数据存取等分开处理。否则你的程序的灵活性会非常地糟,而且随着软件的增大,你的烦恼也会几何级增加。。

#10


我也是做上位机的,程序都差不多样,都不大.
好好分析一下,问题还是好找地.我也一样看不懂你的程序.
如果问题再细化一下,还是可以帮你找到地,必定这里高手如行啊!
加油!

#11


procedure TfrmGarageManageMain.Comm1ReceiveData(Sender: TObject;
  Buffer: Pointer; BufferLength: Word);
var
   i,iGarageNum,iGarageNum1,iGarageNum2,iGarageNum3,b6,b5,b4,b3,b2,b1,b0,WD,RES1:integer;
   bytTemp:byte;
   tempTime,strSQL:string;
begin
    try
       Receivestring:='';
       Move(Buffer^,pchar(@ReceiveData)^,BufferLength);//接收数据
      for i:=1 to BufferLength do
      begin
          Receivestring:=Receivestring+inttohex(ReceiveData[i],2)+' ';
最近查了一下程序,发现上面的语句有数组越界问题,就是这句:for i:=1 to BufferLength do,这个软件是接收无线模块送入串口的数据,有时空中产生误码或干扰一下传上来的字节超过了ReceiveData[i]的定义界限就出现问题,现在改成for i:=1 to 7 do,运行了两天,以为解决了呢,又出现类似问题,弄的我头大,因为是初学Delphi,程序的大框架已经是别人编完的了,实在是找不出问题所在,仍在观察!

#12


问题解决了吗?看这个能行不


var
   Buf:Array[0..1024]OF Char;
Move(Buffer^,Buf,BufferLength);
Receivestring:=String(Buf);

#13


关注

#14


对了在这里
for i:=1 to BufferLength do
      begin
          Receivestring:=Receivestring+inttohex(ReceiveData[i],2)+' ';

改成
for i:=0 to BufferLength-1 do   ////////....
      begin
          Receivestring:=Receivestring+inttohex(ReceiveData[i],2)+' ';

#15


满意结贴,问题已解决,多谢各位!

#1


写数据库另一部分
////////////////////////////////////////////////////////////////////////////////
procedure TfrmGarageManageMain.IsEventOccurMan;  //处理数据,是否有人进入
var
   i:integer;
   h,m,s,mi:word;
   strSQL:string;
begin
   
      //判断人进入情况
      if (ManTime='全天') or ((ManTime='检查时间') and ((formatdatetime('hh:mm',time)>=ManTime1) and (formatdatetime('hh:mm',time)<=ManTime2))  or ((ManTime='停止时间') and ((formatdatetime('hh:mm',time)<=ManTime1) or (formatdatetime('hh:mm',time)>=ManTime2)))) then begin
             //提取数据库,判断是否有记录,并且已经超过了检查间隔时间
             decodetime(now-manLastTime,h,m,s,mi);
             if (h*3600+m*60+s>=manInterval) then begin
               for i:=1 to iGarageCount do begin
                  if ManLBResult[i]=1 then begin
                  //写入数据库
                  strSQL:='select top 1 * from hwjy_ManInout where PLACE='''+GaragePlace+'''';
                  with Q do begin
                     Close;
                     SQL.Clear;
                     SQL.Add(strSQL);
                     Open;
                  end;
                  with Q do begin
                     Append;
                     FieldByName('GARAGE_NO').AsString:=inttostr(i);
                     FieldByName('INTIME').AsDateTime:=now;
                     FieldByName('PLACE').AsString:=GaragePlace;
                     Post;
                  end;
                  ManLastTime:=now;
                  //声音报警
                  PlayWav(Pchar(nWavPath),Pchar('37.wav'),false);
               end;
         end;
      end;//判断有人进入情况
    end;
end;

////////////////////////////////////////////////////////////////////////////////
procedure TfrmGarageManageMain.IsEventOccurFire;  //处理数据,是否有火警
var
   i:integer;
   strSQL:string;
   h,m,s,mi:word;
begin
     //是否启动判断火灾情况
    if (FireTime='全天') or ((FireTime='检查时间') and ((formatdatetime('hh:mm',time)>=FireTime1) and (formatdatetime('hh:mm',time)<=FireTime2)) or ((FireTime='停止时间') and ((formatdatetime('hh:mm',time)<=FireTime1) or (formatdatetime('hh:mm',time)>=FireTime2)))) then begin
        for i:=1 to iGarageCount do begin
         //发生火灾
        if fire[i]>=35 then begin
               //声音报警
             PlayWav(Pchar(nWavPath),Pchar('fire.WAV'),false);
         end;
         end;
        //提取数据库,判断是否有记录,并且已经超过了检查间隔时间
       decodetime(now-FireLastTime,h,m,s,mi);
       if (h*3600+m*60+s>=FireInterval*1) then begin
          FireLastTime:=now;
          for i:=1 to iGarageCount do begin
              //写入数据库
                strSQL:='select top 1 * from hwjy_fire where PLACE='''+GaragePlace+'''';
                with Q do begin
                   Close;
                   SQL.Clear;
                   SQL.Add(strSQL);
                   Open;
                end;
                with Q do begin
                   Append;
                   FieldByName('GARAGE_NO').AsString:=inttostr(i);
                   FieldByName('FIRETIME').AsDateTime:=now;
                   FieldByName('PLACE').AsString:=GaragePlace;
                    if (fireFlag[i]=1) then begin
                     FieldByName('temperature').AsString:='-'+inttostr(fire[i]);
                   end else begin
                     FieldByName('temperature').AsString:=inttostr(fire[i]);
                   end;
                   if fire[i]>=35 then begin
                     FieldByName('type').AsString:='异常';
                   end else begin
                     FieldByName('type').AsString:='未见异常';
                   end;
                   Post;
                end;
             end;
         end;
      end; //判断火灾情况
end;


#2


定时器部分
procedure TfrmGarageManageMain.TimerWriteDataTimer(Sender: TObject);
begin
   ComputeLoop;
   if GarageTurnCount>1 then begin
      comm1.WriteCommData(pAnsiChar(commWriteData[intTurn]),length(commWriteData[intTurn]));
      sleep(20);
      MemoSerial.Lines.Add('车库在第 '+pAnsiChar(inttostr(intTurn)+' 排'));
      MemoSerial.lines.add('');
      intTurn:=intTurn+1;
      if intTurn>GarageTurnCount then intTurn:=1;
   end;
end;



串口接收数据并处理
procedure TfrmGarageManageMain.Comm1ReceiveData(Sender: TObject;
  Buffer: Pointer; BufferLength: Word);
var
   i,iGarageNum,iGarageNum1,iGarageNum2,iGarageNum3,b6,b5,b4,b3,b2,b1,b0,WD,RES1:integer;
   bytTemp:byte;
   tempTime,strSQL:string;
begin
    try
       Receivestring:='';
       Move(Buffer^,pchar(@ReceiveData)^,BufferLength);//接收数据
      for i:=1 to BufferLength do
      begin
          Receivestring:=Receivestring+inttohex(ReceiveData[i],2)+' ';
      end;
        MemoSerial.Lines.Add(Receivestring);
        MemoSerial.lines.add('');
       if (RightStr(inttohex(ReceiveData[1]+ReceiveData[4],1),2))<>inttohex(ReceiveData[5],1) then begin
          tempTime:='有错误发生'+DateTimeToStr(now);
          MemoSerial.Lines.Add(tempTime);
          MemoSerial.lines.add('');
          exit;
        end;
        iGarageNum:=ReceiveData[1]-20;
        car1[iGarageNum]:=(ReceiveData[2] and $80) div $80;
        car2[iGarageNum]:=(ReceiveData[2] and $40) div $40;
        man[iGarageNum]:=(ReceiveData[2] and $08) div $08;
        
        //此处零下温度判断,1为零下,0为零上
        IF (((ReceiveData[3] and $F8) div $F8)=1) then begin
          fireFlag[iGarageNum]:=1;

          b6:=(ReceiveData[3] and $04) div $04;
          if b6=1
          then b6:=0
          else b6:=1;
          b5:=(ReceiveData[3] and $02) div $02;
          if b5=1
          then b5:=0
          else b5:=1;
          b4:=(ReceiveData[3] and $01) div $01;
          if b4=1
          then b4:=0
          else b4:=1;
          b3:=(ReceiveData[4] and $08) div $08;
          if b3=1
          then b3:=0
          else b3:=1;
          b2:=(ReceiveData[4] and $04) div $04;
          if b2=1
          then b2:=0
          else b2:=1;
          b1:=(ReceiveData[4] and $02) div $02;
          if b1=1
          then b1:=0
          else b1:=1;
          b0:=(ReceiveData[4] and $01) div $01;
          if b0=1
          then b0:=0
          else b0:=1;

          RES1:=b6*64+b5*32+b4*16+b3*8+b2*4+b1*2+b0;
          WD:=RES1+1;

          fire[iGarageNum]:=WD;
        end else begin
          fireFlag[iGarageNum]:=0;
          fire[iGarageNum]:=ReceiveData[3]*16+ReceiveData[4]*1;
        end;
        car1Power[iGarageNum]:=(ReceiveData[2] and $20) div $20;
        car2Power[iGarageNum]:=(ReceiveData[2] and $10) div $10;
        if car1Power[iGarageNum]=1 then begin
               with QLog do begin
                  Append;
                  FieldByName('ERRORINFO').AsString:='第 '+inttostr(iGarageNum)+ ' 号车库中1#车辆发生掉电!';
                  FieldByName('TIME').AsDateTime:=now;
                  FieldByName('PLACE').AsString:=GaragePlace;
                  Post;
              end;
        end;
        if car2Power[iGarageNum]=1 then begin
               with QLog do begin
                  Append;
                  FieldByName('ERRORINFO').AsString:='第 '+inttostr(iGarageNum)+ ' 号车库中2#车辆发生掉电!';
                  FieldByName('TIME').AsDateTime:=now;
                  FieldByName('PLACE').AsString:=GaragePlace;
                  Post;
              end;
        end;
         DealwithData; //调用不加滤波的串口处理函数
    except
       exit;
    end;
end;

#3


串口处理后的数据进行滤波
procedure TfrmGarageManageMain.DealWithData;  //串口数据判断,取值为0或者1    0代表不存在事件,1代表存在事件
var
   i:integer;
begin
       //分别滤波,车辆开始滤波
     if LBCount<=LBTimes then begin
       for i:=loopStart to loopEnd do begin
          Car1Count[i]:=Car1Count[i]+car1[i];
          Car2Count[i]:=Car2Count[i]+car2[i];
       end;
     end else begin
         for i:=1 to iGarageCount do begin
         //保存上一次滤波结果
         Car1LBResultOld[i]:=Car1LBResult[i];
         Car2LBResultOld[i]:=Car2LBResult[i];
         //得出本次滤波结果
         if (Car1Count[i]/LBTimes)>LBJunZhi then begin
            Car1LBResult[i]:=1;
            Car1LBResultReal[i]:=1;
         end else begin
            Car1LBResult[i]:=0;
            Car1LBResultReal[i]:=0;
         end;
         if (Car2Count[i]/LBTimes)>LBJunZhi then begin
            Car2LBResult[i]:=1;
            Car2LBResultReal[i]:=1;
         end else begin
            Car2LBResult[i]:=0;
            Car2LBResultReal[i]:=0;
         end;
         Car1Count[i]:=0;
         Car2Count[i]:=0;
      end;
      LBCount:=0;
      IsEventOccur;
     end;


   //人数据情况
      for i:=1 to iGarageCount do begin
          //保存上一次结果
          ManLBResultOld[i] :=ManLBResult[i];
          //得出本次结果
          if man[i]=1 then begin
             ManLBResult[i]:=1;
          end else begin
             ManLBResult[i]:=0;
          end;
      end;
      IsEventOccurMan;
      //火灾数据情况
      IsEventOccurFire;

end;

#4



定时器部分
procedure TfrmGarageManageMain.TimerWriteDataTimer(Sender: TObject);
begin
//----------------------------------------------------------------
进入定时器后应该要执行Timer.Enabled := False;
   ComputeLoop;    if GarageTurnCount>1 then begin
      comm1.WriteCommData(pAnsiChar(commWriteData[intTurn]),length(commWriteData[intTurn]));
      sleep(20);
      MemoSerial.Lines.Add('车库在第 '+pAnsiChar(inttostr(intTurn)+' 排'));
      MemoSerial.lines.add('');
      intTurn:=intTurn+1;
      if intTurn>GarageTurnCount then intTurn:=1;
   end;
//----------------------------------------------------------------
退出时定时器后应该要执行Timer.Enabled := True;

end;

#5


错误信息?

#6


太长了,头晕...........

#7


错误信息在第一个帖子的最下面了,都是警告信息,程序运行一段时间后自动退出!

#8


感觉问题很有可能出在串口接收或写数据库的过程中!

#9


我也是做上位机的,但看了你的代码头大。。。
结构不清晰,程序没有分模块,程序中的常量随处可见,一团糟。。。

建议,将接收模块、控制模块、数据解析、数据存取等分开处理。否则你的程序的灵活性会非常地糟,而且随着软件的增大,你的烦恼也会几何级增加。。

#10


我也是做上位机的,程序都差不多样,都不大.
好好分析一下,问题还是好找地.我也一样看不懂你的程序.
如果问题再细化一下,还是可以帮你找到地,必定这里高手如行啊!
加油!

#11


procedure TfrmGarageManageMain.Comm1ReceiveData(Sender: TObject;
  Buffer: Pointer; BufferLength: Word);
var
   i,iGarageNum,iGarageNum1,iGarageNum2,iGarageNum3,b6,b5,b4,b3,b2,b1,b0,WD,RES1:integer;
   bytTemp:byte;
   tempTime,strSQL:string;
begin
    try
       Receivestring:='';
       Move(Buffer^,pchar(@ReceiveData)^,BufferLength);//接收数据
      for i:=1 to BufferLength do
      begin
          Receivestring:=Receivestring+inttohex(ReceiveData[i],2)+' ';
最近查了一下程序,发现上面的语句有数组越界问题,就是这句:for i:=1 to BufferLength do,这个软件是接收无线模块送入串口的数据,有时空中产生误码或干扰一下传上来的字节超过了ReceiveData[i]的定义界限就出现问题,现在改成for i:=1 to 7 do,运行了两天,以为解决了呢,又出现类似问题,弄的我头大,因为是初学Delphi,程序的大框架已经是别人编完的了,实在是找不出问题所在,仍在观察!

#12


问题解决了吗?看这个能行不


var
   Buf:Array[0..1024]OF Char;
Move(Buffer^,Buf,BufferLength);
Receivestring:=String(Buf);

#13


关注

#14


对了在这里
for i:=1 to BufferLength do
      begin
          Receivestring:=Receivestring+inttohex(ReceiveData[i],2)+' ';

改成
for i:=0 to BufferLength-1 do   ////////....
      begin
          Receivestring:=Receivestring+inttohex(ReceiveData[i],2)+' ';

#15


满意结贴,问题已解决,多谢各位!