Spcomm连续接收多位数据。 ( 积分: 100 )

  • 主题发起人 主题发起人 yocheng
  • 开始时间 开始时间
Y

yocheng

Unregistered / Unconfirmed
GUEST, unregistred user!
我现在要连续接收 XX XX XX XX XX XX XX XX XX XX 0D 多位字节。共11位,请问我如何每次只接收11位字节,每次都是0D结束。
 
不应该这样想 ,应该是考虑把数据接收回来后进行分解。如果你知道开始位和长度,或者你知道结束符,都很容易分解的。控制接收的位数这样的控制方式,好像不如直接分解接收内容好处理。
 
to zywcd
请问具体怎样操作?因为发送机那很快地不停地这样发数过来。我都不知如何去处理。
 
不停的发是对的。你定义一个公共变量,把接收的字符串加在一起,然后进行分解。
 
给你一个程序参考,这个是电子秤的接收程序,使用了spcomm.每次完整的通讯是使用字符g结束 。你的是会车。
//注意:电子秤设置为秤重完成发数据。
procedure Tinput_Form.Comm1ReceiveData(Sender:TObject; Buffer:Pointer;
BufferLength:Word);
var t:pchar;
b:integer;
t1:string;
k:single;
p1:integer;
begin
//通讯返回字符串。|ST,GS,+0003.30 g
t:=Buffer;
t1:=t;
k:=0;
//新的电子称程序
//取小数点前4位,后3位
repeat
b:=Pos('g',t1);
if b>10 then
begin
p1:=Pos('.',t1);
if p1>0 then
begin
try
k:=strtofloat(Trim(copy(t1,p1-5,9)));
except k:=0;
end;
end
else
k:=0;
if k>=0.1 then
break; //如果重量达到一定,则退出。
t1:=copy(t1,b+1,Length(t1));
end
else
Exit;
until Pos('g',t1)=0;

if (k<=0.099) then
Exit;

Edit17.Text:=formatfloat('0.000',k);
Edit25.Text:=formatfloat('0',k*strtofloat(Edit22.Text));
Edit2.Text:=formatfloat('0',k*strtofloat(Edit29.Text));
SpeedButton18.Click; //保存数据。
Edit35.Text:=CreateBar(Edit35.Text); //产生商品条码。
Panel4.caption:=ComboBox13.Text+ComboBox15.Text; //填入商品名称。
end;
 
应该这样做

// 在窗口的定义中加入一个方法去处理已经组帧的数据
type
TForm1 = class(TForm)
...
private
procedure OnDataReceived(pData: Pointer; DataLen: Integer);
end;

// 在模块头定义一个全局的数据二级缓冲区
var
RxBuff: array [0..255] of Byte;
RxBufLen: Integer;

procedure TForm1.Comm1ReceiveData(Sender:TObject; Buffer:Pointer; BufferLength:Word);
var
I, N: Integer;
begin
Move(PByte(Buffer)^, RxBuff[RxBufLen], BufferLength);
Inc(RxBufLen, BufferLength);
N:= 0;
for I:= 0 to RxBufLen - 1 do if RxBuff = $0D then begin
OnDataReceived(@RxBuff[N], I-N+1);
N:= I + 1;
end;
if N <> 0 then begin
Dec(RxBufLen, N);
Move(RxBuff[N], RxBuff[0], RxBufLen);
end;
end;

procedure TForm1.OnDataReceived(pData: Pointer; DataLen: Integer);
begin
// 你的数据处理
end;

好,该有分进帐了吧,嘻嘻
 
不好意思,现在正在看,行立刻给分。呵呵。。。。
 
TO zywcd
你的我试过不行,可能我的数据他发过来,数值只是11个字节中的4-9字节
 
to:
SupermanTm
我的数据处理那里不时很明白你的意思,如我要显示那数在edit1.text里,如何做。
 
// 在这里定义一个全局变量, 最好在Form里定义, 在form的onCreate中初始化 := '';
var rst : string = '';

procedure TFrom1.comdrvReceiveData(Sender: TObject; DataPtr: Pointer;
DataSize: Cardinal);
var p: pchar;
begin
p := DataPtr;
while DataSize > 0 do
begin
if p^ = #13 then
begin
if (length(rst) > 0) then // 也可以加上其他条件, 例如: if (length(rst)=10) then
begin
edit1.text := rst; // 在这里处理你的事务
end;
rst := ''; // 清空
end else
begin
rst := rst + p^;
end;
dec( DataSize );
inc( p );
end;
end;
 
如果你需要显示十六进制的数字,那么在TForm1.OnDataReceived里:
procedure TForm1.OnDataReceived(pData: Pointer; DataLen: Integer);
var
I, X: Integer;
S: String;
begin
SetLength(S, DataLen * 3);
for I:= 0 to DataLen - 1 do begin
X:= I * 3 + 1;
PShortString(@S[X])^:= IntToHex(PByteArray(pData)^, 2);
S[X]:= ',';
end;
S[1]:= ' ';
Edit1.Text:= S;
end;
 
不过,如果你的数据是不间断地送来的,建议不要用 TEdit 去显示,用个 TMemo,然后把上面代码的最后一句
Edit1.Text:= S;
改成
Memo1.Lines.Add(S);
这样就看得更清楚了
 
多人接受答案了。
 
后退
顶部