⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 econv230p.pas

📁 Delphi编写的ModBus协议上位机软件
💻 PAS
📖 第 1 页 / 共 4 页
字号:
      57600: b57600.Checked := true;
      115200: b115200.Checked := true;
      128000: b128000.Checked := true;
      256000: b256000.Checked := true;
      else
      begin
        buser.Checked := true;
      end;
    end; // end case econfile.comm.baudrate

    m_address.Items[econfile.comm.rtuaddress-1].Checked := true;

    // 初始化通讯相关参数
    vacomm1.Close;
    vacomm1.Baudrate := changbaudrate(econfile.comm.baudrate);
    vacomm1.UserBaudrate := econfile.comm.userbaud;
    vacomm1.Databits := changdatabits(econfile.comm.databits);
    vacomm1.Stopbits := changstopbits(econfile.comm.stopbits);
    vacomm1.Parity := changparity(econfile.comm.parity);
    vacomm1.PortNum := econfile.comm.portnum;
    sendtimer.Enabled := false;
    revtimer.Enabled := false;
    sendtimer.Interval := 1;
    timerout1.Interval := econfile.comm.timeout;
    m_comset.Enabled := true;
//    readholdregister(econfile);
//    readfifo(econfile);
  end;//end with mainform do
end;

//----------------------窗口激活处理-------------------------
procedure TMainForm.FormActivate(Sender: TObject);
begin
  mainform.Caption := companyname;
end;

//----------------------数据定义文件保存---------------------
procedure TMainForm.saveClick(Sender: TObject);
begin
  datamemo.Lines.SaveToFile(getfilename);
end;

//----------------------打开数据定义文件处理-----------------
procedure TMainForm.fileopenClick(Sender: TObject);
begin
  stop_comm;
  if (true=open1.Execute) then getfilename := open1.FileName
     else exit;
  mainform.Caption := companyname+'----'+getfilename;
  system_init;
end;

//----------------------接收定时处理-------------------------
procedure TMainForm.revtimerTimer(Sender: TObject); //接收数据
var
   a,b:integer;
   j:char;
   FirstString:String; //':'数据包头标识
   SecondString:String;//两字节板地址
   TemStr:String;
begin
  timeoutcount := timeoutcount + 1;

  if (Uppercase(econfile.comm.mode)='ASCII') then
  begin
       if timeoutcount>timerout1.Interval+10 then
       begin
         timerout1.Enabled := TRUE;
         timeoutcount := 0;
       end;

       TemStr := Vacomm1.ReadText;
       receiveString := receiveString+ TemStr;

       a := Pos(':',receiveString); // 找出冒号的位置
       if (a>1) then Delete(receiveString,1,a-1); // 删除冒号以前的字符
       FirstString := Copy(receiveString,1,1);

       b := Pos(#13#10,receiveString); // 找结束符
       if (b=0) then exit;

       timerout1.Enabled := TRUE;
       sendtimer.Enabled := TRUE;
       for a:=2 To b-1 do //检查出错帧
       begin
           SecondString := Copy(receiveString,a,1);
           if not((SecondString[1] in ['0'..'9'])or( SecondString[1]
                 in ['a'..'f'])or( SecondString[1] in ['A'..'F']))then
           begin
             Delete(receiveString,1,b+1);
             exit;
           end;
       end;
       temstr := copy(receivestring,1,b+1);
       delete(receivestring,1,b+1);

       revmemo.Lines.text := revmemo.Lines.text+temstr;
       if (revmemo.Lines.count>20) then
       begin
         revmemo.lines.clear;
         revmemo.lines.add('接收数据');
       end;

       framecheck;
       asclltoapp(temstr,econfile);
       app_analys(econfile);

  end;//if ascii mode

  if (Uppercase(econfile.comm.mode)='RTU') then
  begin
    if timeoutcount>=(13*1000/econfile.comm.baudrate) then
    begin
      if (framecheck = 0)and(read_index>0) then
      begin
        for a:=0 to read_index-1 do econfile.analysbuffer[a+1]:=revbuff[a];
        app_analys(econfile);
        for a:=0 to 1024 do revbuff[a]:=0;

        //timerout1.Enabled := false;
        sendtimer.Enabled := TRUE;
        poll_count := 0;
        revtimer.Enabled := False;
        //timeoutcount := 0;
        revmemo.Lines.Text := revmemo.Lines.Text+#13;

        if (revmemo.Lines.count>20) then
        begin
          revmemo.lines.clear;
          revmemo.lines.add('接收数据');
        end;
      end
      else
      begin
        timerout1.Enabled := TRUE;
      end;
    end;
  end;
end;

//----------------------发送定时处理-------------------------
procedure TMainForm.sendtimerTimer(Sender: TObject);
var
  temp: string;
  i: integer;
  j: integer;
  sendbuff: array[1..8]of byte;
  sendstring: string;
begin
  //if (UpperCase(econfile.comm.mode)='RTU') then
  //begin

  poll_count := poll_count+1;
  if (poll_count<=econfile.comm.timepoll) then exit;
  //end;

  timerout1.Enabled := true; //发送开始计数

  {i := 0;
  while (econfile.comm.sendbuffer2.buffer[econfile.comm.sendbuffer2.index]='') do
  begin
      i := i+1;
      if i > 50  then
      begin
        break;  // 无插入帧,跳出循环
      end;
      econfile.comm.sendbuffer2.index := (econfile.comm.sendbuffer2.index + 1) mod 50  ;
  end;

    // 如果无插入帧则发正常帧数据
  if (econfile.comm.sendbuffer2.buffer[econfile.comm.sendbuffer2.index]='') then
  begin
      while (econfile.comm.sendbuffer1.buffer[econfile.comm.sendbuffer1.index]='') do
      begin
        econfile.comm.sendbuffer1.index := (econfile.comm.sendbuffer1.index + 1) mod 50 ;
      end;
      econfile.comm.sendbuffer := econfile.comm.sendbuffer1.buffer[econfile.comm.sendbuffer1.index];
      econfile.comm.sendbuffer1.index := (econfile.comm.sendbuffer1.index + 1) mod 50  ;
    end
    else
    begin
      econfile.comm.sendbuffer := econfile.comm.sendbuffer2.buffer[econfile.comm.sendbuffer2.index];
      econfile.comm.sendbuffer2.buffer[econfile.comm.sendbuffer2.index] := ''; //送入发送区后删除插入值
      econfile.comm.sendbuffer2.index := (econfile.comm.sendbuffer2.index + 1) mod 50  ;
  end;}

  if (econfile.comm.sendbuffer3<>'') then
  begin
    econfile.comm.sendbuffer := econfile.comm.sendbuffer3;
    econfile.comm.sendbuffer3 := '';
  end
  else
  if (econfile.comm.sendbuffer4<>'') then
  begin
    econfile.comm.sendbuffer := econfile.comm.sendbuffer4;
    econfile.comm.sendbuffer4 := '';
  end
  else
  begin
    if (econfile.comm.sendbuffer2.buffer[econfile.comm.sendbuffer2.index]='') then
    begin
      i := 0;
      while (econfile.comm.sendbuffer2.buffer[econfile.comm.sendbuffer2.index]='') do
      begin
         if (i=50)  then break;
         econfile.comm.sendbuffer2.index := (econfile.comm.sendbuffer2.index + 1) mod 50 ;
         i := i+1;
      end; //search a true frame ready to send

      while (econfile.comm.sendbuffer1.buffer[econfile.comm.sendbuffer1.index]='') do
      begin
         econfile.comm.sendbuffer1.index := (econfile.comm.sendbuffer1.index + 1) mod 50 ;
      end;
      econfile.comm.sendbuffer := econfile.comm.sendbuffer1.buffer[econfile.comm.sendbuffer1.index];
      econfile.comm.sendbuffer1.index := (econfile.comm.sendbuffer1.index + 1) mod 50 ;
    end
    else
    begin
      sendflag1 := not sendflag1;
      if (sendflag1) then
      begin
        econfile.comm.sendbuffer := econfile.comm.sendbuffer2.buffer[econfile.comm.sendbuffer2.index];
        econfile.comm.sendbuffer2.buffer[econfile.comm.sendbuffer2.index] := ''; //送入发送区后删除插入值
        econfile.comm.sendbuffer2.index := (econfile.comm.sendbuffer2.index + 1) mod 50 ;
      end
      else
      begin
        while (econfile.comm.sendbuffer1.buffer[econfile.comm.sendbuffer1.index]='') do
        begin
          econfile.comm.sendbuffer1.index := (econfile.comm.sendbuffer1.index + 1) mod 50 ;
        end;
        econfile.comm.sendbuffer := econfile.comm.sendbuffer1.buffer[econfile.comm.sendbuffer1.index];
        econfile.comm.sendbuffer1.index := (econfile.comm.sendbuffer1.index + 1) mod 50 ;
      end;
    end;
  end;

  if (UpperCase(econfile.comm.mode)='RTU') then
  begin
    sendbuff[1] := econfile.comm.rtuaddress;
    sendbuff[2] := strtohex1(copy(econfile.comm.sendbuffer,1,2),2);
    beginaddress := strtohex1(copy(econfile.comm.sendbuffer,3,4),4);
    sendbuff[3] := beginaddress div 256;
    sendbuff[4] := beginaddress mod 256;

    if (sendbuff[2]=$1) then
    begin
      readcoilcount := strtohex1(copy(econfile.comm.sendbuffer,7,4),4);
    end;
    if (sendbuff[2]=$2) then
    begin
      readinputcount := strtohex1(copy(econfile.comm.sendbuffer,7,4),4);
    end;
    if (sendbuff[2]=$5) then
    begin
      //addsendbuffer2(econfile,'01'+inttohex(beginaddress,4)+'0001');
    end;
    if (sendbuff[2]=$18) then
    begin
      j := crc(sendbuff[1],4);
      sendbuff[5] := j div 256;
      sendbuff[6] := j mod 256;
      temp := '';
      for j:=1 to 6 do temp := temp + inttohex(sendbuff[j],2);
      Vacomm1.WriteBuf(sendbuff,6);
    end
    else
    begin
      sendbuff[5] := strtohex1(copy(econfile.comm.sendbuffer,7,4),4)div 256;
      sendbuff[6] := strtohex1(copy(econfile.comm.sendbuffer,7,4),4)mod 256;
      j := crc(sendbuff[1],6);
      sendbuff[7] := j div 256;
      sendbuff[8] := j mod 256;
      temp := '';
      for j:=1 to 8 do temp := temp + inttohex(sendbuff[j],2);
      Vacomm1.WriteBuf(sendbuff,8);
    end;

    sendmemo.Lines.Add(temp);
    if sendmemo.lines.count>20 then
    begin
        sendmemo.lines.clear;
        sendmemo.lines.Add('发送数据');
    end;
  end;

  if (UpperCase(econfile.comm.mode)='ASCII') then
  begin
    sendstring := inttohex(econfile.comm.rtuaddress,2);
    beginaddress := strtohex1(copy(econfile.comm.sendbuffer,3,4),4);
    i := strtohex1(copy(econfile.comm.sendbuffer,1,2),2);
    if (i=1) then
    begin
      readcoilcount := strtohex1(copy(econfile.comm.sendbuffer,7,4),4);
    end;

    if (i=2) then
    begin
      readinputcount := strtohex1(copy(econfile.comm.sendbuffer,7,4),4);
    end;

    if (i=5) then
    begin
      //addsendbuffer2(econfile,'01'+inttohex(beginaddress,4)+'0001');
    end;

    sendstring := sendstring + econfile.comm.sendbuffer;
    sendstring := sendstring + lrc(sendstring);
    begin
       vacomm1.WriteText(':'+sendstring+#13#10);
       sendmemo.Lines.Add(':'+sendstring+#13);
       if (sendmemo.lines.count>20) then
         begin
           sendmemo.lines.clear;
           sendmemo.lines.Add('发送数据');
         end;
     end
  end;

  sendtimer.Enabled := False;
  poll_count := 0;
  revtimer.Enabled := True;
  timeoutcount := 0;
  read_index := 0;
end;


//----------------------通讯开启控制-------------------------
procedure TMainForm.m_comcontrolClick(Sender: TObject);
begin
  if (not comm_status) then
  begin
    if  (econfile.comm.timeout <= 1.5*econfile.comm.timepoll) then
    begin
      showmessage('超时时间应大于1.5倍发送帧间隔时间,请修改');
      exit;
    end
    else
    start_comm;//开始通讯
  end
  else
  begin
    stop_comm;//关闭通讯
  end;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -