★(高分求助)我发现串口通讯控件spcom的一个bug,谁帮我研究一下★(300分)

  • 主题发起人 主题发起人 龙月
  • 开始时间 开始时间

龙月

Unregistered / Unconfirmed
GUEST, unregistred user!
下面的代码大家在网上肯定经常看到,但是我昨天发现一个奇怪的情况。
就是我们发送的是F0 01 FF FF 01 F0,端口也能收到同样的数据,
但是如果我们发送的数据中含有11,就收不到。真奇怪。
比如我把sbuf[1]:=byte($f0); 改成sbuf[1]:=byte($11);
那样就收不到这个数据, 这是个很严重的bug,而且太奇怪了,那么多数据,为什么
偏偏是$11不行呢,想不通,我的信箱是yzdzc@163.com


--------------------------------------
在Delphi中用SPCOMM实现串口编程
Delphi是一种具有功能强大、简便易用和代码执行速度快等优点的可视化快速应用开发工具
,它在构架企业信息系统方面发挥着越来越重要的作用,许多程序员愿意选择 Delphi作为
开发工具编制各种应用程序。但是,美中不足之处是 Delphi没有自带的串口通信控件,
在它的帮助文档里也没有提及串口通信,这就给编制通信程序的开发人员带来许多不便。

目前,利用 Delphi实现串口通信的常用的方法有 3种:一是利用控件,如 MSCOMM控件和
SPCOMM控件;二是使用 API函数;三是调用其他串口通信程序。其中利用 API编写串口通
信程序较为复杂,需要掌握大量的通信知识。相比较而言,利用 SPCOMM控件则相对较简单
,并且该控件具有丰富的与串口通信密切相关的属性及事件,提供了对串口的各种操作,
而且还支持多线程。下面本文结合实例详细介绍 SPCOMM控件的使用。
编写源代码

//变量说明

var

fcomm: TFCOMM;

viewstring:string;

i:integer;

rbuf,sbuf:array[16] of byte;

//打开串口

procedure TFCOMM.FormShow(Sender: TObject);

begin

comm1.StartComm;

end;

//关闭串口

procedure TFCOMM.FormClose(Sender: TObject; var Action: TCloseAction);

begin

comm1.StopComm;

end;

//自定义发送数据过程

procedure senddata;

var

i:integer;

commflg:boolean;

begin

viewstring:='' ;

commflg:=true;

for i:=1 to 6 do

begin

if not fcomm.comm1.writecommdata(@sbuf,1) then

begin

commflg:=false;

break;

end;

//发送时字节间的延时

sleep(2);

viewstring:=viewstring+ inttohex(sbuf,2)+'' ; end;

viewstring:=‘发送’+ viewstring;

fcomm.memo1.lines.add(viewstring);

fcomm.memo1.lines.add('' );

if not commflg then messagedlg('发送失败 !' ,mterror,[mbyes],0);

end;

//发送按钮的点击事件

procedure TFCOMM.Btn_sendClick(Sender: TObject);

begin

sbuf[1]:=byte($f0); //帧头 //★★★★ 在这里如果我发送的是$11就不行★★★★

sbuf[2]:=byte($01); //命令号 //★★★★ 在这里如果我发送的是$11就不行★★★★


sbuf[3]:=byte($ff); ////★★★★ 在这里如果我发送的是$11就不行★★★★


sbuf[4]:=byte($ff);

sbuf[5]:=byte($01);

sbuf[6]:=byte($f0); //帧尾

senddata;//调用发送函数

end;

//接收过程

procedure TFCOMM.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;BufferLength: Word);

var

i:integer;

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;

如果 memo1上显示发送 F0 01 FF FF 01 F0和接收到 F0 01 FF FF 01 F0,这表示串口已正确地发送出数据并正确地接收到数据,则串口通信成功。

 
spcomm不是很好,有很多更好的通讯控件可以用
 

这不是BUG,
仔细看一下属性设置。。。有两个字符有这个现象,是可选的
我觉得SPCOMM很好用。。。
 
11与13是SPCOMM的协议字符.
只要设置一下属性可行了.
 
xiao_min朋友,您帮了我大忙,虽然是个简单的问题,但是我一下子想不到,害的我苦忙了半天,
真的很感谢您,我还想象您请教一下,XoffChar和XonChar 是干嘛用的,我在为我公司编写
电气设备和PC机的通讯软件,我们只用rs-232口的2,3,5.还有什么rts ,cts我们都不用,
我把XoffChar和XonChar 的属性清空,但是没用,它会设成#0,所以我发$00就收不到了,
真麻烦,我怎样才能收到所有的16进制数呢?
 
我是把那些什么ON OFF控制的都设为FALSE
 
我以前也遇到过这种问题,把Outx_XonXoffFlow改为False后,丢字节问题即可解决($11,$13也可以出现了)。
 
先保存一下...明天再来
 
还有一个问题,就是pccom这个控件里有一个属性parityCheck,它是布尔型的,这个属性是
干什么用的,如果为false,那么发送的字节中是不是就没有效验位。
 
这个属性无所谓,只要上位机跟下位机设置一样就行了,至于检验关键还是在自己的数据中
自己进行处理
 
resun朋友,照您这么说,parityCheck属性不影响parity属性了。
也就是说即使parityCheck:=false,奇偶效验位也起效果。
 
我今天调试了终端设备,发出去老是接受不到数据,我想那位朋友用spcom控件做过相关软的
,能不能发一份源码给我。 yzdzc@163.com
 
后退
顶部