请问我用spcomm控件连续发送了4条指令,现在我想每发一条指令就要收到该条指令的反馈指令,如何实现呀? ( 积分: 100 )

  • 主题发起人 主题发起人 doby_li
  • 开始时间 开始时间
D

doby_li

Unregistered / Unconfirmed
GUEST, unregistred user!
请问我用spcomm控件连续发送了4条指令,现在我想每发一条指令就要收到该条指令的反馈指令,但我现在只能收到第一条指令的反馈指令,其它三条反馈指令都收不到。
相关代码:
procedure TFCOMM.btninitClick(Sender: TObject);
var
sinit1,sinit2,sinit3,sinit4:string;
begin

//初始化 1
sinit1:=HexToStr('6899999999999968050161CD16');
if Comm1.WriteCommData(Pchar(sinit1),Length(sinit1)) then
else
messagedlg('初始化卡的指令1发送失败!',mterror,[mbyes],0);
sleep(2);

//写数据初始化 2
sinit2:=HexToStr('68999999999999680301016B16');
if Comm1.WriteCommData(Pchar(sinit2),Length(sinit2)) then
else
messagedlg('初始化卡的指令2发送失败!',mterror,[mbyes],0);
sleep(2);

//写返写区初始化 3
sinit3:=HexToStr('68999999999999680301026C16');
if Comm1.WriteCommData(Pchar(sinit3),Length(sinit3)) then
else
messagedlg('初始化卡的指令3发送失败!',mterror,[mbyes],0);
sleep(2);

//返写区清零 4
sinit4:=HexToStr('6899999999999968040A353332323232323232326C16');
if Comm1.WriteCommData(Pchar(sinit4),Length(sinit4)) then
else
messagedlg('初始化卡的指令4发送失败!',mterror,[mbyes],0);

end;
以上是在一个“初始化”的按纽中连续发送4条指令。

procedure TFCOMM.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
var s:string;
begin
SetLength(S,BufferLength); //接收RS232的数据并显示Memo1上。
Move(Buffer^,PChar(S)^,BufferLength);
Memo1.Lines.Add(StrToHex(S));
Memo1.Invalidate;

//if StrToHex(S)='68 FF FF FF FF FF FF 68 C5 01 62 F2 16' then
// showmessage('初始化卡的操作成功!');
end;

以上代码只能收到第一条发送指令的反馈指令,请问应如何改才能实现:每发送一条指令就收到一条反馈指令.

打个比方:
发送A指令,收到A1指令。
发送B指令,收到B1指令。
发送C指令,收到C1指令。
发送D指令,收到D1指令。

先谢各位了。
 
2,3,4的指令放在procedure TFCOMM.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
中处理,并发送
 
发送A指令,等待..收到A1指令/超时。-->
发送B指令,等待..收到B1指令/超时。-->
发送C指令,等待..收到C1指令/超时。-->
发送D指令,等待..收到D1指令/超时。-->
 
wrf和nicai_wgl先生能不能详细一点说一下呀。
很急呀,这事。
谢谢。
 
wrf:
你好,我按你说的我把第二条指令的发送和接收放到Comm1ReceiveData中去了,但程序会一直执行"第二条指令的发送和接收"呀,如何让它只执行一次呀?
 
自已顶!难道无人这样做过吗?
每次都是只发一条指令的吗?
 
//先定义一个全局变量用来判断接收是否正确
var RXdata:integer;
//发送
procedure TFCOMM.btninitClick(Sender: TObject);
var
sinit1;
begin
//初始化 1
sinit1:=HexToStr('6899999999999968050161CD16');
Comm1.WriteCommData(Pchar(sinit1),Length(sinit1));
RXdata:=1;
//接收
procedure TFCOMM.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
var s:string;
begin
SetLength(S,BufferLength); //接收RS232的数据并显示Memo1上。
Move(Buffer^,PChar(S)^,BufferLength);
//case 或者 if 随意了
if (s=A1指令) and (RXdata=1) then 发送B指令同时RXdata计数加一 else
if (s=B1指令) and (RXdata=2) then 发送C指令同时RXdata计数加一 else
if (s=C1指令) and (RXdata=3) then 发送D指令同时RXdata计数加一 else
if (s=D1指令) and (RXdata=4) then showmessage('就是这么简单啊,兄弟!');
else showmessage('我靠!有没有搞错,是不是你的卡坏了阿!);
 
原理我就不说了,如果可行,到时候给分的时候多分点

声明一个全局的事件对象,hEvent
在窗体建立的时候,比如Form的OnCreate里面建立一个事件对象,
hEvent := CreateEvent(nil, True, False, nil);

在窗体关闭的时候
CloseHandle(hEvnet);


然后你上面的
sleep(2);
都修改成
WaitForSingleObject(hEvent, INFINITE);
ResetEvent(hEvent);

另外在
Comm1ReceiveData函数的结尾,加上SetEvent(hEvent)

就是 //if StrToHex(S)='68 FF FF FF FF FF FF 68 C5 01 62 F2 16' then
// showmessage('初始化卡的操作成功!');
的位置

基本上应该就可以了,如果不行就加我qq
 
我也遇到过这种问题,我的解决方法是用一个定时器,每发一条指令就延时一段时间,估计这点时间能收完数据了就发下一条指令,不知道你发命令是否频繁,如果不频繁,我觉得我的方法可行
 
用TSimpleEvent
代码如下:

procedure TForm1.FormCreate(Sender: TObject);
begin
Event := TSimpleEvent.Create;
Event.SetEvent;
end;
 
我用bluedyness的方法搞定了,不过大家的方法都不错。
 
多人接受答案了。
 
后退
顶部