求助:关于spcomm 接收数据的问题..急...分不够可以再加.谢谢.(200分)

  • 主题发起人 主题发起人 chukaiwang
  • 开始时间 开始时间
C

chukaiwang

Unregistered / Unconfirmed
GUEST, unregistred user!
最近在做医院一台Elec 2010 (电化学发光)仪器的数据接受..每次发接受的数据解码出来都不对...请各位帮忙指导一下...
procedure TTestComFrm.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
var
i:integer;
viewstring:string;
rbuf:array[1..8] of byte;
begin
//=============================================
viewstring:='' ;
move(buffer^,pchar(@rbuf)^,bufferlength);
for i:=1 to bufferlength do
viewstring:=viewstring+ inttohex(rbuf,2)+'' ;
viewstring:='接收:'+ viewstring;
memo1.lines.add(viewstring);
memo1.lines.add('');
end;
//=========以下是我的测试记录
我设了断点跟踪
move(buffer^,pchar(@rbuf)^,bufferlength);
这时的值是 0,57,1,85,0,6,0
最后得到的viewstring的值 是'05'
仪器上的输出的结果是 105 1407 CA125 18.06
 
检查波特率要一样
 
move(buffer^,rbuf,bufferlength);
波特率,协议都要一致,另外发送接受数据要有延时,根据数据量多少设置延时长短。否则可能数据发送接受不全
 
to :lxw5214
波特率是的设置成一样的了...协议对方供应商说不需要握手协议..我也不知道在哪里设置
请指教.....
 
//=============================================
viewstring:='' ;
move(buffer^,pchar(@rbuf)^,bufferlength); //接收的数据长度确认是8吗?会不会溢出?
for i:=1 to bufferlength do //这里也是,大于8时出错
viewstring:=viewstring+ inttohex(rbuf,2)+' | ' ;//这里最好加个分隔符 '|'
viewstring:='接收: '+ viewstring;
memo1.lines.add(viewstring);
memo1.lines.add('');
end;
 
楼主最好向供货商要份详细的说明书,通讯方式,数据格式,二进制的还是字符型的。
按你的测试记录看,返回的数据应该是字符型的,而且长度也不止8个。
可以改成如下试试:
procedure TTestComFrm.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
var
i:integer;
viewstring:string;
rbuf:array[1..256] of byte;
begin
//=============================================
viewstring:='' ;
move(buffer^,pchar(@rbuf)^,bufferlength);
for i:=1 to bufferlength do
viewstring:=viewstring+ Char(rbuf);
viewstring:='接收:'+ viewstring;
memo1.lines.add(viewstring);
memo1.lines.add('');
end;
 
我说的不是握手协议,是指数据格式,就是他发来的数据的每个字节代表什么意思,有没有校验位之类的。比如我是按帧来发的,有帧头段,数据段,校验段,一共68个字节,每部分都有自己代表的意思。这个你需要他们提供,不然发来了数据都不知道是干什么的,还可以先找个串口调试工具,接受一下发来的数据,分析一下
 
一般都使用十六进制,字符是用ascii码来传输的
 
我也要开始这样的项目了,受益!
 
var rbuf:array[0..50] of char;
begin
move(buffer^,rbuf,bufferlength);
i:=10;
edit1.Text:=copy(rbuf,1,15);
end;
绝对解决的
 
zhaozedidai你这个程序在表示什么东西,不要误导别人好不好![:)]
 
一小段不完整的程序,因为我原来写的程序太长,所以给你一点参考一下。有好多工作要做,你先要像lxw5214说的那样,搞清楚消息格式,才可以继续你的工作,也可以多通过串口调试程序,截获一点消息自己分析看看。

只是提供你参考,加上了好多注释,应该是完全可以看懂得。使用的SPCOMM控件,有一些变量在这个函数里面没有定义,你最好注意一下,因为有的变量我用了全局变量。

procedure TForm1.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
var
DECS,HEXS,Msg: String;
i: Integer;
FN:String; //命令参数
begin
DECS:='';
HEXS:='';
//接收RS232的数据并显示Memo1上。
Move(Buffer^,RBuf1,BufferLength);

RX1:=RX1+BufferLength; //消息长度
RXP1.Caption:=' RX1: '+IntToStr(RX1); //在通讯面板上显示接收到的消息长度
RXP1.Color:=CLLIME; //接收消息时,通讯面板显示绿色,表示正在接收信息
Application.ProcessMessages;

For i:=1 to BufferLength do //数据接收过程按照每个字节进行处理
begin
Sleep(1) //接收延迟,你可以自己决定通讯需要延时的时间,可以长一点也可以不延时
HEXS:=HEXS+inttohex(RBuf1,2)+''; //HEX Disp 16进制显示,对于有些看不到的消息可以做调试。如STX或者SOH等命令字符。
DECS:=DECS+Char(RBuf1); //DEC Disp 10进制显示,ASCII码元显示没有任何问题。
end;

Memo1.Lines.Add('COM Recv '+DateTimeToStr(NOW)+' TXT ---> '+DECS); //以ASCII码元方式显示接收到的消息
Memo1.Lines.Add('COM Recv '+DateTimeToStr(NOW)+' HEX ---> '+HEXS); //以16进制方式显示接收到的消息

Memo1.Lines.Add('...');

if SFCB1.Checked=True then //是否记录到Log记录中
begin
Write(LogFile1,'MICROS Recv '+DateTimeToStr(NOW)+' TXT ---> '+DECS+#10); //以ASCII码元方式将消息写入Log文件
Write(LogFile1,'MICROS Recv '+DateTimeToStr(NOW)+' HEX ---> '+HEXS+#10); //以16进制方式将消息写入Log文件

Write(LogFile1,'...'+#10);
end;

Application.ProcessMessages;
RXP1.Color:=CLWhite; //接收消息结束,通讯面板恢复白色,表示消息接收过程结束。
Application.ProcessMessages;

//数据接收后的处理过程
if (Copy(DECS,1,1)=SOH)and(Copy(DECS,Length(DECS),1)=EOH) then //接收到的消息正确封装方式已经被接收 SOH,EOH已经在前面定义,每个通讯程序都可能不同,但是SOH一般是#01,STX是#02,ETX是#03,EOH是#04,EQU是#05,ACK是#06,NAK是#15等等,还有好多消息编码方式,还有CRC、MD5或其他的Checksum码元。

begin
//正确接收到消息,可能有重复消息队列要分段处理
repeat
TP:=Copy(DECS,1,POS(EOH,DECS));
Msg:=Pchar(TP);

然后还需要将Msg拆开分析,因为当中还有命令消息符号和参数符号,等等信息。

给你一个消息文本格式做参考:中国电信 IP Hotel提供的TCP/IP接口和RS232接口的文本协议的一小点看看,因为这个通讯文本太长了,有10几页,所以就给你看一句好了。

激活卡号消息应答 //一种可以充值的中国电信宽带上网卡接口消息
使用:接口发送给PMS,为激活卡号的应答
PMSI --> PMS
格式:AR|DN|RT|CN|C1|P1|C2|P2|C3|P3|C4|P4|C5|P5|
AR 激活卡号消息应答的消息标识(ActCard Response)
DN 编码号码 必须
RT 返回码 必须(10为成功,其余为失败)
CN 卡号数n(1<=n<=5) 只有在返回码正确时才返回此开卡个数
C1 第一张卡卡号
P1 第一张卡密码
C2 第二张卡卡号
P2 第二张卡密码
C3 第三张卡卡号
P3 第三张卡密码
C4 第四张卡卡号
P4 第四张卡密码
C5 第五张卡卡号
P5 第五张卡密码

.........还有很多,省略!!!

注意,该消息应该有祯头和祯尾,因此,一个完整的消息为
<STX>AR|DN|RT|CN|C1|P1|C2|P2|C3|P3|C4|P4|C5|P5|<ETX>

消息发送格式:
<STX>AR|DN1001|RT10|CN3|C12001@test|P1aaa|C2 2002@test|P2aaa|C32003@test|P3aaa|<ETX>
消息回应格式:
<STX>AR|DN1001|RT11|<ETX>

这些通讯中有命令分隔符还有参数,所以要分析清楚才可以的,而且每一个又有专门的定义。

好好研究吧,希望对你有一点参考作用。
 
多人接受答案了。
 
后退
顶部