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

📄 unit1.~pas

📁 RS232串口通讯随书源码
💻 ~PAS
字号:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls, TComm1;

type
  TForm1 = class(TForm)
    rdCOM: TRadioGroup;
    mReceive: TMemo;
    Comm1: TComm;
    Timer1: TTimer;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    procedure Button4Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Procedure TimeDelay(DT:DWORD);
  Function TypeRange(ch:Byte):String;
  Function Status_Val(c3,C4:Byte):Single;

implementation

{$R *.DFM}

procedure TForm1.Button4Click(Sender: TObject);
begin
  //确定使用的通信端口号码
  if rdCOM.ItemIndex =0 then
    Comm1.CommPort := pnCOM1
  else
    Comm1.CommPort := pnCOM2;
  //打开通信端口
  Comm1.PortOpen := True;
end;

//以下是延迟函数,单位毫秒
Procedure TimeDelay(DT:DWORD);
var
 TT:DWORD;
begin
  //取得现在的Tick值
  TT:=GetTickCount();
  //计算Tick差值是否超过设置值
  while GetTickCount()-TT<DT do
   Application.ProcessMessages; //释放控制权
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 Buf:string;
 ByteBuf:array of Byte;
 Count,i:Integer;
 DataPT:PByte;
begin
  //设置传输量
  Comm1.InputLen := 0;
  Buf := Comm1.Input ;
  TimeDelay(100);
  //送出空格符(Chr(32))
  Comm1.OutputString(' ');
  TimeDelay(300);
  if Comm1.DataCount <5 then
  begin
    ShowMessage('电功率计未返回正确的信息');
    exit;
  end;
  //读取返回的数据
  Count := Comm1.ReadInputByte(DataPT);
  //重新设置数组范围
  SetLength(ByteBuf,5);
  Dec(DataPT); //将字节指针减1
  for i:=0 to 4 do
   begin
    Inc(DataPt); //将字节指针加1
    ByteBuf[i] := DataPT^; //取出数据
   end;
  //检查前后字符是否正确 
  if ord(ByteBuf[0])<>2 then
  begin
    ShowMessage('前导字符不正确');
    exit;
  end;
  if ord(ByteBuf[4])<>3 then
  begin
    ShowMessage('结尾字符不正确');
    exit;
  end;
  mReceive.Text := '电功率计已准备妥当!';
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  //控制定时器的运作
  Timer1.Enabled := not Timer1.Enabled ;
  if Timer1.Enabled then
    Button2.Caption := '停止读值'
  else
    Button2.Caption := '读功率值';
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
  Comm1.PortOpen := False;
  //结束系统
  Close;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
 Buf:string;
 C2,C3,C4:Byte;
 ByteBuf:array[0..4] of Byte;
 ByteCmd:array[0..4] of Byte;
 Count,i:Integer;
 DataPT:PByte;
begin
  Comm1.InputLen := 0;
  Buf := Comm1.Input ; //清空缓冲区
  //设置要求字符,并送出
  ByteCmd[0] := 241;
  ByteCmd[1] := 13;
  Comm1.OutputByte(Bytecmd);
  TimeDelay(300);
  if Comm1.DataCount <5 then
  begin
    mReceive.Text := '电功率计未返回正确的信息';
    exit;
  end;
  //取得返回的数据
  Count := Comm1.ReadInputByte(DataPT);
  Dec(DataPT);
  //以下循环将数据送进数组
  for i:=0 to 4 do
   begin
    Inc(DataPt);
    ByteBuf[i] := DataPT^;
   end;
  //判断前后字符是否OK 
  if ord(ByteBuf[0])<>2 then
  begin
    ShowMessage('前导字符不正确');
    exit;
  end;
  if ord(ByteBuf[4])<>3 then
  begin
    ShowMessage('结尾字符不正确');
    exit;
  end;
  //取得各字符
  C2 := ByteBuf[1];
  C3 := ByteBuf[2];
  C4 := ByteBuf[3];
  //将取得的字符送进子程序中判断
  //并显示到Memo组件中
  mReceive.Text := 'Range=' + TypeRange(C2) + Chr(13)+Chr(10);
  mReceive.Text := mReceive.Text +
    FormatFloat('0.00',Status_val(C3,C4)) ;  

end;

//此函数用来判断测量的范围
Function TypeRange(ch:Byte):String;
begin
  //根据所返回的字符检查所属的测量范围
  case ord(ch) of
   3:Result := '200V';
   4:Result := '1000V';
   5:Result := 'Hz';
   49:Result := '2.0A';
   33:Result := '20.0A';
   192:Result := '200W';
   193:Result := '2000W';
   208:Result := 'PF';
   255:Result := 'Hold'
   else
   Result := '2.0A';
  end;
end;

//此函数用来计算取得电功率值
Function Status_Val(c3,C4:Byte):Single;
var
  T1,T2,T3,T4:String;
  PosNeg,Code:Integer;
  ValueString:String;
  DecimalValue:Single;  //小数点乘数
  ReadValue:Single;
begin
  If (c3 And $1)=1 Then     //正负号
    PosNeg := 1
  Else
    PosNeg := -1;
  If (c3 And $2)=$2 Then     //第1位数
    T1 := '1'
  Else
    T1 := '0' ;
   //使用shr及shl可以向右或向左移动位,以达到
   //书中的位计算法则
   T2 := IntToStr(((c3 And $20) shr 5) * 1 + ((c3 And $10) shr 4) * 2
         + ((c3 And $8) shr 3) * 4 + ((c3 And $4) shr 2) * 8); //第2位数
   T3 := IntToStr(((c4 And $2) shr 1) * 1 + ((c4 And $1) shl 1)
         + ((c3 And $80) shr 7) * 4 + ((c3 And $40) shr 6) * 8); //第3位数
   T4 := IntToStr(((c4 And $20) shr 5) * 1 + ((c4 And $10) shr 4) * 2
         + ((c4 And $8) shr 3 )* 4 + ((c4 And $4) shr 2) * 8); //第4位数
   ValueString := T1 + T2 + T3 + T4;
   Val(ValueString,ReadValue,Code);
   ReadValue := ReadValue* PosNeg;
  //检查小数点位置
  If ((c4 And $80) = 0) And ((c4 And $40) = 0) Then DecimalValue := 1;
  If ((c4 And $80) <> 0) And ((c4 And $40) = 0) Then DecimalValue := 10;
  If ((c4 And $80) = 0) And ((c4 And $40) <> 0) Then DecimalValue := 100;
  If ((c4 And $80) <> 0) And ((c4 And $40) <> 0) Then DecimalValue := 1000;
  //将计算的结果返回
  Result := ReadValue / DecimalValue;

end;

end.

⌨️ 快捷键说明

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