仪表的通讯中,指令码出错 急哭了,在线等(20分)

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

carrie4002

Unregistered / Unconfirmed
GUEST, unregistred user!
仪表的通讯中,SPCOMM的WriteCommData()函数
遇到问题了。
指令字串:':volt:dc:nplc 10'
在VB.net里,用COM控件实现的代码是:
Comb.Output = "syst:rwl" & Chr(10),其中,Chr(10)为
命令串结束符;
在Delphi6中,用SPCOMM来实现时,WriteCommData()这句
该怎么写?
 
怎么没人关注啊?
诚请!
 
Chr(10)=#10
 
最初我的代码也是:
Str:=pchar(‘*cls’+ #10);
WriteCommData(Str, Length(Str));
连机调试出错时,才意识到#10在VB里是命令结束符,
但在Delphi里,SPCOMM里也是结束符吗?
 
Str:=pchar(':disp:text:stat off'+ #10);
WriteCommData(@Str, Length(Str));这两句与:
Str:=pchar(':disp:text:stat off #10');
WriteCommData(@Str, Length(Str));
有何不同吗?
 
肯定不同,前一方法是在末尾加换行符,后一方法的'#10'是字符串。
你查一下命令结束是以#10还是#13或者是两个组合。
 
to lzh7735:
谢谢你。
在VC++里,发送指令为:strcpy(OutputData,":disp:text:stat off/n")
'/n'是硬回车作为命令结束符,和命令字符串放在引号里;
在VB.net里。命令是:Comb.Output = ":disp:text:stat off" & Chr(10),
还是加了Chr(10)作为命令结束符。
所以,在DELPHI里,代码该怎么写?
 
大虾们怎么都无动于衷啊?
 
var ss:string;
begin
ss:=':disp:text:stat off'+#13;
Comm1.WriteCommData(addr(ss[1]),Length(ss));
end;
试试这个
 
var
str:pchar;
begin
Str:=':disp:text:stat off'#10#0;
WriteCommData(Str, strlen(Str));
注:C中的/n 为#13
 
var
str: String; //用string
begin
str ;= 'xxx' + #10;
if writecommdata(pchar(str),length(str)) then
xxx
end;

我刚用不久,这样就可以,如果你想用pchar,那一定要注意指针,上面的pchar相加是无效的,没有将#10加进去

如果要用pchar省转换的话,一般都要用move先转到pchar数组中去
 
To wlong01 and foam:
谢谢你们。代码都过。
#10#0是什么意思?

TO 诸葛:
谢谢。
现在可以和和仪表通讯了。只是在通讯连接结束时,
用一条指令取初始化电压值时,触发了Comm1ReceiveData(),
在这个过程中出错了,并中断。
如果,读出的数是一个float值,还可能是负数,且不知道该
值到底有多少位,Comm1ReceiveData()里该注意些什么?
 
你从CommReceiveData里面只能读出一个buffer,对于你说的负数和float值,是跟你们自己的定义有关的,例如收到的第一个字节如果是某个值,就代表负数,等等.
你可以在CommReceiveData事件中定义
procedure TFrm1.CommReceiveData(Sender: TObject; Buffer: Pointer; BufferLength: Word);
var
lnI: Integer;
RevStr, RevChar: String;
ReceiveBuf: array[0..65535] of byte;
begin
RevStr := '';
RevChar := '';

FillChar(ReceiveBuf, SizeOf(ReceiveBuf), 0);
Move(Buffer^, ReceiveBuf, BufferLength);

for lni:=0 to BufferLength-1 do
begin
RevStr := RevStr + IntToHex(ReceiveBuf[lni], 2) + ' ';
RevChar := RevChar + Char(ReceiveBuf[lni]) ;
end;
//然后根据你的需要,使用收到的数据,就可以了
end;
 
TO guanweiw:
谢谢。你的思路我试试。
 
不能使用pchar,改为如下
Str:=':disp:text:stat off'+ #10;
WriteCommData(Str, Length(Str));

CommReceiveData中触发的数据根据硬件的协议进行分析,如果返回的仅仅是一个数值的话,可以这样处理:
RevData: String;
Load: real;

RevData=pchar(Buffer) ;
try
Load:=strtofloat(RevData) ;
except
end ;
 
TO ahhlian,:
谢谢你关注。guanweiw的指令代码我调试已经通过,
WriteCommData(Str, Length(Str))的Str必须是指针类
型,否则编译通不过。
你的接收代码,我测试是通过的。谢谢你。
 
在接收的时候记得多注意一些非法数据的保护,以免程序崩溃
 
诸葛谢谢你。
还有一个问题,在通讯及数据处理的这个窗口代码里,串口
通讯分连接、读取、关闭三个过程。在需要的地方单独调用。
比如下面这个语句,放在连接过程里必须加窗体名,否则提示
未定义,Form2.Comm1.CommName:='COM3';可真正执行时,还是
这里出错。总之,只要放在过程里,就根本不执行。但把相同的
指令代码放在按纽代码里,则不必加窗体名就执行。如
Comm1.CommName:='COM3'就可以。
为什么?该如何解决这个问题。
 
你定义的连接过程,可能不是在这个Form类中声明的过程,所以在使用这个Form类的变量时,要加入窗体名.当你放在按钮代码里时,这个按钮首先是属于这个Form类的,所以就不需要加窗体名了.你可以将你的连接过程,在Form类的私有处声明,然后在调用,应该就可以了.
 
TO guanweiw:谢谢你。
如果我的过程或者函数是这样的:
Function comm1_Rev():Double;
procedure comm2_sndData();
该怎么在Private里定义?
 
后退
顶部