X
xiaoke
Unregistered / Unconfirmed
GUEST, unregistred user!
我程序的实现思想是:
当按发送按钮时,先将这个按钮disnable,并发送握手信号d1d5,根据对方返回的信息是不是
cc,若是,则将要发送的数据发送过去,延时一段时间后,发送按钮enable。若返回的信号
不是cc,则表明握手失败,清空缓冲区,再次发送握手信号,直到返回的值为cc。为了防止对方收到
后很长一段时间不给返回信号而导致不能再次发送数据,我用了一个ttimer控件(运行期创建),
放在发送缓冲区空里面,如果一段时间没有收到信号,则将刚才的发送按钮enable,以便可以
再次发送数据,并把这个ttimer给free掉。
以下是我的程序,有一个问题,那就是ttimer控件触发的事件,但是判断的结果却
不是ttimer,导致程序没有按照预期的情况运行。
procedure TForm1.EzComPort1TxEmpty(Sender: TObject);
//var mytimer:TTimer;
begin
timeouttimer:=TTimer.create(self);
timeouttimer.interval:=rxtimelimit;
timeouttimer.onTimer:=ezcomport1rxchar;
timeouttimer.Enabled:=true;
ezcomport1.onrxchar:=ezcomport1rxchar;
//showmessage('yijinchenggongfasong');
end;
procedure TForm1.EzComPort1RxChar(Sender: TObject);
var
x,y:integer;
begin
if Sender is ttimer then//判断是不是ttimer触发的
begin
timeouttimer.ontimer:=nil;
ezcomport1.onrxchar:=nil;
case buttonid of //判断按下哪个按钮
1: yazhenmdtj.lmdbutton21.enabled:=true;
2: suozitlw.lmdbutton1.enabled:=true;
3: machinetest.lmdbutton1.enabled:=true;
4:juanqultz.lmdbutton1.enabled:=true;
else
showmessage('你按了什么按钮?');
end;
timeouttimer.free;
// showmessage('com device timeout!');
end else
begin {以下用了二级缓存,防止多收}
x:=ezcomport1.inque;
y:=rxdatalength-(rxbytecount);
x:=ezcomport1.read(rxbuf2[rxbytecount+1],y);
inc(rxbytecount,x);
if rxbytecount>=rxdatalength then
begin
ezcomport1.PurgeIn;
ezcomport1.PurgeOut;
timeouttimer.ontimer:=nil;
ezcomport1.onrxchar:=nil;
timeouttimer.free;
end;
machinetest.Memo1.lines.add(inttostr(rxbuf2[1]));
if (rxbuf2[1]=204) then
begin
// rxbuf2[1]:=0;
EzComport1.Write(glbS[1], c);//glbs[1]为保存的欲发送的数据
sleep(2);
ezcomport1.PurgeIn;
ezcomport1.PurgeOut;
case buttonid of
1: yazhenmdtj.lmdbutton21.enabled:=true;
2: suozitlw.lmdbutton1.enabled:=true;
3: machinetest.lmdbutton1.enabled:=true;
4:juanqultz.lmdbutton1.enabled:=true;
else
showmessage('你按了什么按钮?');
end;
end else
begin
glbs:=#$D1#$D5;
EzComport1.Write(glbS[1], 2);
end;
end;
end;
procedure Tmachinetest.LMDButton1Click(Sender: TObject);
var
s:string;
begin
lmdbutton1.enabled:=false;
buttonid:=3;
case lmdradiogroup1.Itemindex of
0: begin
glbs:=#$a6;
c:=1;
end;
1: begin
glbs:=#$a7;
c:=1;
end;
2: begin
glbs:=#$a8#$01#$b0;
c:=3;
end;
end;
SetLength(RxBuf2, RxDataLength);
RxByteCount:= 0;
woshou:=#$D1#$D5;
form1.EzComport1.Write(woshou[1], 2);
end;
我按了一次发送按钮后,对方返回的第一次返回我收不到,必须是对方在不停的发送的时候
,我再按发送按钮,而当第一次通讯成功后,我不在按发送按钮,对方也不再给我发信息,
我的却还不停的发送刚刚发送的那个信息,也就是说是ttimer控件触发EzComPort1RxChar,但是在事件
里判断的结果却不是ttimer触发,不知道是什么原因,因为如果执行ttimer触发里面的程序,就不会再次的发送,
而只有在判断不是的情况下,才判断是不是rbuf2=204,因为这是个二级缓存,所以在
没有清空之前一直成立,所以就一直的发送。而且跟对方发送数据的时间间隔有关系,如果对方
不停的发,那我就有可能接收到数据,否则很可能接收不到,按理说每次有数据到达,都会
触发EzComPort1RxChar事件,我都可以接收的阿,到底是什么原因阿?
还有,如果对方不停的发,就会出现异常,是不是缓冲区满了就会出现这种情况阿?
该怎样解决那?出现异常的地方是WaitForSingleObject(Overlapped.hEvent, INFINITE);
if not GetOverlappedResult(ComHandle, Overlapped, BytesRead, False);是不是读的方法不对阿?
最后问一下,对方发送的16进制数,我能不能先用字符串去接收,然后再转化为
16进制阿?我试过好像不行阿?我用的是tcomport控件的改良,是一个热心的好友
,也是delphi的高手给我的,该怎样接收从单片机发送回来的信息那?请高手帮忙指点和解决一下,万分感激!!
当按发送按钮时,先将这个按钮disnable,并发送握手信号d1d5,根据对方返回的信息是不是
cc,若是,则将要发送的数据发送过去,延时一段时间后,发送按钮enable。若返回的信号
不是cc,则表明握手失败,清空缓冲区,再次发送握手信号,直到返回的值为cc。为了防止对方收到
后很长一段时间不给返回信号而导致不能再次发送数据,我用了一个ttimer控件(运行期创建),
放在发送缓冲区空里面,如果一段时间没有收到信号,则将刚才的发送按钮enable,以便可以
再次发送数据,并把这个ttimer给free掉。
以下是我的程序,有一个问题,那就是ttimer控件触发的事件,但是判断的结果却
不是ttimer,导致程序没有按照预期的情况运行。
procedure TForm1.EzComPort1TxEmpty(Sender: TObject);
//var mytimer:TTimer;
begin
timeouttimer:=TTimer.create(self);
timeouttimer.interval:=rxtimelimit;
timeouttimer.onTimer:=ezcomport1rxchar;
timeouttimer.Enabled:=true;
ezcomport1.onrxchar:=ezcomport1rxchar;
//showmessage('yijinchenggongfasong');
end;
procedure TForm1.EzComPort1RxChar(Sender: TObject);
var
x,y:integer;
begin
if Sender is ttimer then//判断是不是ttimer触发的
begin
timeouttimer.ontimer:=nil;
ezcomport1.onrxchar:=nil;
case buttonid of //判断按下哪个按钮
1: yazhenmdtj.lmdbutton21.enabled:=true;
2: suozitlw.lmdbutton1.enabled:=true;
3: machinetest.lmdbutton1.enabled:=true;
4:juanqultz.lmdbutton1.enabled:=true;
else
showmessage('你按了什么按钮?');
end;
timeouttimer.free;
// showmessage('com device timeout!');
end else
begin {以下用了二级缓存,防止多收}
x:=ezcomport1.inque;
y:=rxdatalength-(rxbytecount);
x:=ezcomport1.read(rxbuf2[rxbytecount+1],y);
inc(rxbytecount,x);
if rxbytecount>=rxdatalength then
begin
ezcomport1.PurgeIn;
ezcomport1.PurgeOut;
timeouttimer.ontimer:=nil;
ezcomport1.onrxchar:=nil;
timeouttimer.free;
end;
machinetest.Memo1.lines.add(inttostr(rxbuf2[1]));
if (rxbuf2[1]=204) then
begin
// rxbuf2[1]:=0;
EzComport1.Write(glbS[1], c);//glbs[1]为保存的欲发送的数据
sleep(2);
ezcomport1.PurgeIn;
ezcomport1.PurgeOut;
case buttonid of
1: yazhenmdtj.lmdbutton21.enabled:=true;
2: suozitlw.lmdbutton1.enabled:=true;
3: machinetest.lmdbutton1.enabled:=true;
4:juanqultz.lmdbutton1.enabled:=true;
else
showmessage('你按了什么按钮?');
end;
end else
begin
glbs:=#$D1#$D5;
EzComport1.Write(glbS[1], 2);
end;
end;
end;
procedure Tmachinetest.LMDButton1Click(Sender: TObject);
var
s:string;
begin
lmdbutton1.enabled:=false;
buttonid:=3;
case lmdradiogroup1.Itemindex of
0: begin
glbs:=#$a6;
c:=1;
end;
1: begin
glbs:=#$a7;
c:=1;
end;
2: begin
glbs:=#$a8#$01#$b0;
c:=3;
end;
end;
SetLength(RxBuf2, RxDataLength);
RxByteCount:= 0;
woshou:=#$D1#$D5;
form1.EzComport1.Write(woshou[1], 2);
end;
我按了一次发送按钮后,对方返回的第一次返回我收不到,必须是对方在不停的发送的时候
,我再按发送按钮,而当第一次通讯成功后,我不在按发送按钮,对方也不再给我发信息,
我的却还不停的发送刚刚发送的那个信息,也就是说是ttimer控件触发EzComPort1RxChar,但是在事件
里判断的结果却不是ttimer触发,不知道是什么原因,因为如果执行ttimer触发里面的程序,就不会再次的发送,
而只有在判断不是的情况下,才判断是不是rbuf2=204,因为这是个二级缓存,所以在
没有清空之前一直成立,所以就一直的发送。而且跟对方发送数据的时间间隔有关系,如果对方
不停的发,那我就有可能接收到数据,否则很可能接收不到,按理说每次有数据到达,都会
触发EzComPort1RxChar事件,我都可以接收的阿,到底是什么原因阿?
还有,如果对方不停的发,就会出现异常,是不是缓冲区满了就会出现这种情况阿?
该怎样解决那?出现异常的地方是WaitForSingleObject(Overlapped.hEvent, INFINITE);
if not GetOverlappedResult(ComHandle, Overlapped, BytesRead, False);是不是读的方法不对阿?
最后问一下,对方发送的16进制数,我能不能先用字符串去接收,然后再转化为
16进制阿?我试过好像不行阿?我用的是tcomport控件的改良,是一个热心的好友
,也是delphi的高手给我的,该怎样接收从单片机发送回来的信息那?请高手帮忙指点和解决一下,万分感激!!