从指针类型变量中取出部分数据的问题(200分)

  • 主题发起人 主题发起人 nslhw
  • 开始时间 开始时间
N

nslhw

Unregistered / Unconfirmed
GUEST, unregistred user!
Comm1ReceiveData(Sender: TObject
Buffer: Pointer
BufferLength: Word)
串口访问控件读取缓冲区数据的事件,返回一个指针buffer,以及返回的数据长度word,返回的数据中,从第10个字节开始,每4个字节代表一个浮点数,请问怎么将这么些浮点数分离取出来放到浮点型的变量里。只举取一个浮点数的例子就可以了。
 
uses Types;

////////////////////////////////////////////////////////////////////////////////
//设计:Lsuper 2008.01.28
//功能:返回的数据中,从第10个字节开始,每4个字节代表一个浮点数,将浮点数分离出来
//参数:
////////////////////////////////////////////////////////////////////////////////
procedure ReceiveData(Buffer: Pointer
BufferLength: Word;
var F: TSingleDynArray);
var
nCount: Integer;
pData: PChar;
begin
nCount := (BufferLength - 9) div 4;
SetLength(F, nCount);
pData := Buffer;
Inc(pData, 9);
Move(pData^, PChar(F)^, nCount * 4);
end;
 
//Delphi 进制转换——十六进制 to 十进制浮点数
//十进制 to 二进制
function IntToBin(Value: LongInt;Size: Integer): String;
var
i: Integer;
begin
Result:='';
for i:=Size-1 downto 0 do begin
if Value and (1 shl i)<>0 then begin
Result:=Result+'1';
end else begin
Result:=Result+'0';
end;
end;
end;

//二进制 to 十进制

function BintoInt(Value: String): LongInt;
var
i,Size: Integer;
begin
Result:=0;
Size:=Length(Value);
for i:=Size downto 1 do
begin
if Copy(Value,i,1)='1' then
Result:=Result+(1 shl (Size-i));
end;
end;

function floatBintoInt(Value: String): real;
var
i,Size: Integer;
begin
Result:=0;
Size:=Length(Value);
for i:=Size downto 1 do
begin
if Copy(Value,i,1)='1' then
Result:=Result+1/(1 shl i);
end;
end;

//十六进制 to 二进制

function HextoBinary(Hex:string):string;
const
BOX: array [0..15] of string =
('0000','0001','0010','0011',
'0100','0101','0110','0111',
'1000','1001','1010','1011',
'1100','1101','1110','1111');
var
i:integer;
begin
for i:=Length(Hex) downto 1 do
Result:=BOX[StrToInt('$'+Hex)]+Result;
end;

//十六进制 to 十进制 浮点型
function HextoFloat(s:string):real;
var b,temp:string;
e:integer;
f:real;
begin
b:=HextoBinary(s);
temp := copy(b,2,8);
e:=BintoInt(temp)-127;
temp := copy(b,10,23);
f := 1+floatBintoInt(temp);
if(copy(b,1,1)='0')then
result := power(2,e)*f
else
result :=-power(2,e)*f;
end;

----------

Sample:

Edit1.text:='40A33964'
//注意:浮点数为四字节,高位在前低位在后

edit2.text:= format('%1.3f',[HextoFloat(Edit1.text)])
//输出为5.101

Comm1ReceiveData(Sender: TObject
Buffer: Pointer
BufferLength: Word)
var
RevData: array[1..N] of byte ;
sData : string ;
fData : real ;
begin
move(Buffer^,RevData,N);
sData := inttohex(RevData[10])+inttohex(RevData[11])+inttohex(RevData[12])+inttohex(RevData[13]) ;
fData :=HextoFloat(Edit1.text)
//第一个数据,注意高低位区别
end ;
 
注意浮点数的格式是否和Delphi中single类型一致,不一致需要自己做变换。
 
Comm1ReceiveData(Sender: TObject
Buffer: Pointer
BufferLength: Word);
var
pf: PSingle;
f1, f2: Single;
begin
pf := PSingle(Cardinal(Buffer) + 9);
// 先决条件,低字节在前,高字节在后;否则把那四个字节顺序先调整好
f1 := pf^;
Inc(pf);
f2 := pf^;
....
end;
 
procedure Comm1ReceiveData(Sender: TObject
Buffer: Pointer
BufferLength: Word);
type
TMyRec = packed record
Prefix: array [0..9] of Byte;
Data: array [0..0] of Single;
end;
PMyRec = ^TMyRec;
var
P: PMyRec;
I, N: Integer;
begin
P:= Buffer;
N:= (BufferLength - 10) div 4;
for I:= 0 to N - 1 do begin
DoMyProcess(P^.Data)
// 自己写这个处理过程
end;
end;
 
你的浮点数是4个字节 对应 Single 类型

uses
Classes;

Comm1ReceiveData(Sender: TObject
Buffer: Pointer
BufferLength: Word)
var
sList: TStringList;
iCount: Integer;
I: Integer;
Buf2K: array[0..2047] of Byte
//设置2k的缓冲区
Buf: array[0..3] of Byte;
begin
sList := TStringList.Create;
try
iCount := (BufferLength - 9) div 4;
Move(Buffer, Buf2K, BufferLength);

for I := 0 to iCount - 1 do
begin
Move(Buf2K[I * 4 + 10], Buf, 4);
sList.Add(Single(Buf);
end;
sList.SaveToFile('C:/11.txt');
finally
sList.Free;
end;
end;
 
现在正在学习这方面的东西,关注中……
 
后退
顶部