📄 unit1.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 + -