请教一个串口通讯的问题!(200分)

  • 主题发起人 主题发起人 jafy
  • 开始时间 开始时间
协议中是不是定义了,当校验和出错时下为机的返回数据
你的教研和是不是有问题
 
TO jafy:
你发给我的Log文件我以收到,但给你回复的时候邮件被退回来了[:(!],现在我在上海[:D]
根据Log文件分析,前面的一部分可以是程序自动控测哪一个串口连接有可用设备,这些实际上都可以转换成API来实现,如:
14 20:47:16 TRWIN VCOMM_OpenComm COM2 SUCCESS
// ComHandle:=CreateFile('COM2',GENERIC_READ or GENERIC_WRITE,0,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
15 20:47:16 TRWIN VCOMM_SetupComm COM2 SUCCESS RxSize: 1024 TxSize: 512
// SetupComm(ComHandle,1024,512);
16 20:47:16 TRWIN VCOMM_SetCommState COM2 SUCCESS Mask: ffffffff Baud: 9600 Bits: 7 Stop: 1 Parity: Even
// SetCommState(ComHandle,FDCB); DCB的设置查看帮助
17 20:47:16 TRWIN VCOMM_SetCommEventMask COM2 SUCCESS
// SetCommMask(CommHandle,...);
18 20:47:16 TRWIN VCOMM_EscapeCommFunction COM2 SUCCESS GETCOMBASEIRQ
// EscapeCommFunction ...
19 20:47:16 TRWIN VCOMM_SetCommState COM2 SUCCESS Mask: ffffffff Baud: 9600 Bits: 8 Stop: 1 Parity: None
// SetCommState
20 20:47:16 TRWIN VCOMM_SetCommEventMask COM2 SUCCESS
// SetCommMask
21 20:47:16 TRWIN VCOMM_PurgeComm COM2 SUCCESS Receive Queue
// PurgeComm
...

看以看到,VCOMM_...后面的字符串基本上就是调用了对应的API函数,最后一列就是其参数
根据这些信息,稍加分析一下,完全可以重新实现一遍这个过程了
建议你用SpComm这个控件,带全部源码,分析它会对你有帮助

回到主题上来,我觉得对于前面自动检测设备这一部分完全可以忽略,由你来指定使用哪一个串口,这样程序也会简化许多,
53 20:47:26 TRWIN VCOMM_WriteComm COM2 SUCCESS Length: 2: 00 00
// 连续写入两个 0,可能与下一条指令有一定的间隔时间
54 20:47:26 TRWIN VCOMM_WriteComm COM2 SUCCESS Length: 1: 11
// 写入一个 11,可能与下一条指令有一定的间隔时间
55 20:47:26 TRWIN VCOMM_WriteComm COM2 SUCCESS Length: 1: EE
// 写入一个 EE,可能与下一条指令有一定的间隔时间
用mscomm来实现,如下
mscomm.output:=#0#0;
sleep(5); //延时5毫秒
mscomm.output:=#$11;
sleep(5);
mscomm.output:=#$EE;
用Spcomm实现,如下:
var
Cmd: Array[0..1] of Byte;
begin
FillChar(Cmd,2,#0);
SpComm.WriteCommData(@Cmd,2)
Sleep(5);
Cmd[0]:=$11;
SpComm.WriteCommData(@Cmd,1)
Sleep(5);
Cmd[0]:=$EE;
SpComm.WriteCommData(@Cmd,1)
end;
如果有数据返回的话,处理控制的事件就可以了

如果以上操作仍然不行的话,那你就再调节调节各种参数,多多调试,相信你总会成功的![:D]
 
你可以先试一下要发的字符的十六进制码。
如:
var
tmp_1:array [0..1] of char;
tmp_2:array [0..1] of char;
begin
tmp_1[0]:=#$53; //'S' 的十六进制码,当然也可以发'S'
tmp_1[1]:=#0;
Comm1.WriteCommData(@tmp_1,1);//发送'S'
Sleep(5); //延时5ms
//用同样的方法发下一个变量
//一定行的。
 
十分感谢各位的帮助,尤其是PIHOME和蒋劲刚的帮助,虽然问题没有完全解决,但是已经找到一条线索了,相信多实验一下应该能成功!但是我还发现一个问题,我用SPCOMM控件,不知道为何发了Comm1.WriteCommData(@tmp_1,1)后没有马上发生OnReceiveData事件?这样我就不能在一个按钮的CLICK事件中连续执行2个以上的命令串?或者是SPCOMM有类似MSCOMM.INPUT的事件,还有如何清空接受缓冲区的数据?谢谢![:)]
 
不会的!我经常在一个过程中向设备发很多指令也回读很多回应的,不会有问题。
你发完一条指令后要等它回应后再发第二个指令呀。
接收缓冲区不用手工清空的,在COMM的ONRECIEVEDATA事件发生过后,它就会被自动清空的
 
TO:蒋劲刚
可如何才能得到它的回应呢?他没有像MSCOMM一样的INPUT事件呀?
 
还有,如果使用MSCOMM控件,输入mscomm.output:=#$EE;用PORTMON跟踪后只显示为输入的是00,而不是EE,这是为何?
 
1有啊,就是ONRECIEVEDATA事件
2你看一下你的流控件符是什么?你是不是启用了软件流控制呀
 
请教:蒋劲刚
流控制的属性是哪个?我使用以下的代码,但一运行就出错,请问为何?
sBuf[0]:=$62;
sBuf[1]:=$04;
sBuf[2]:=$86;
sBuf[3]:=$76;
sBuf[4]:=$A6;
sBuf[5]:=$31;
sBuf[6]:=$0D;
Sleep(5);
iscable:=false;
if not Comm1.WriteCommData(@sBuf,7) then
showmessage('error')
else
begin
Sleep(200);
if iscable=true then //此过程想得到在ONRECIEVEDATA中判断如果返回值与发送值相同则ISBABLE:=TRUE,但这里不知道为何,总是为FALSE,我只有把下面的显示加到ONRECIEVEDATA事件中判断。
status.Panels[0].Text := 'Found:[IC-101]Cable!'
else
begin
status.Panels[0].Text := 'NOT Find any Cable!';
exit;
end;
//———————以下过程开始执行第二个循环后就出错,为何?———————//

for i:=1 to 14 do
begin
Cmd[0]:=$47;
Comm1.WriteCommData(@Cmd,1);
Sleep(5);
Cmd[0]:=$B8;
Comm1.WriteCommData(@Cmd,1);
sleep(100);
end;
sleep(200);
 
还没搞定么?
SpComm.XonChar XoffChar为软件流控字符

>>Sleep(200);
>>if iscable=true then //此过程想得到在ONRECIEVEDATA中判断如果返回值与发送值相
>>同则ISBABLE:=TRUE,但这里不知道为何,总是为FALSE,我只有把下面的显示加到
>>ONRECIEVEDATA事件中判断。
Sleep后主线程就停止了,不会执行任何代码的,而且也不该是在这里判断
应该是在OnReceiveData中判断接收到的字符串是不是预期的结果,再执行相应的操作

//———————以下过程开始执行第二个循环后就出错,为何?———————//
看起来似乎没有什么错误,仔细检查你的程序,看是哪有影响到了?
 
多人接受答案了。
 
后退
顶部