读书人

spcomm当出现多个串口时的数据接收异常

发布时间: 2012-04-03 12:38:19 作者: rapoo

spcomm当出现多个串口时的数据接收错误?
服务器有6个串口,对应都有数据过来,故放置了6个SPCOMM控件,结果发现一个问题,那怕仅是打COM1端口,其它端口不打开,所以接收的数据与发送的数据完全不对,但只要把其余5个SPCOMM接收地了事件下面的接收代码全部去掉就可以正常的接收了,一放上去就不行了,就是乱码接收到的,具体代码如下:同时确认参数设置是没有问题的。
procedure TMainFrm.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
var
ch:char;
i:integer;
begin
BCallStr1:='';
BCallState:='';
BCallNo:='';
{move(buffer^,pchar((@rbuf)^),bufferlength);
for i:=0 to bufferlength-1 do
begin
BCallStr1:=BCallStr1+inttohex(ord(rbuf[i]),2); //16进位制按2位一组读出数据
end; }
for i:=0 to BufferLength-1 do
begin
ch:=(pchar(buffer)+i)^;
BCallStr1:=BCallStr1+ch;
end;
StatusBar1.Panels.Items[0].Text:=Bcallstr1;
BCallNo:=copy(BCallStr1,3,4);
BCallState:=copy(BCallStr1,1,2); //获取呼叫器工作状态标示
mainfrm.ComRevSendSMS;
end;

下面都是一样的
procedure TMainFrm.Comm2ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
begin
{ BCallStr2:='';
BCallState:='';
BCallNo:='';
move(buffer^,pchar((@rbuf)^),bufferlength);
for i:=0 to bufferlength-1 do
begin
BCallStr2:=BCallStr2+inttohex(ord(rbuf[i]),2); //16进位制按2位一组读出数据
end;
StatusBar1.Panels.Items[0].Text:=Bcallstr2;
BCallNo:=copy(BCallStr2,3,4);
BCallState:=copy(BCallStr2,1,2); //获取呼叫器工作状态标示
mainfrm.ComRevSendSMS; }
end;

procedure TMainFrm.Comm3ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
begin
{BCallStr3:='';
BCallState:='';
BCallNo:='';
move(buffer^,pchar((@rbuf)^),bufferlength);
for i:=0 to bufferlength-1 do
begin
BCallStr3:=BCallStr3+inttohex(ord(rbuf[i]),2); //16进位制按2位一组读出数据
end;
StatusBar1.Panels.Items[0].Text:=Bcallstr3;
BCallNo:=copy(BCallStr3,3,4);
BCallState:=copy(BCallStr3,1,2); //获取呼叫器工作状态标示
mainfrm.ComRevSendSMS; }
end;

procedure TMainFrm.Comm4ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
begin
{BCallStr4:='';
BCallState:='';
BCallNo:='';
move(buffer^,pchar((@rbuf)^),bufferlength);
for i:=0 to bufferlength-1 do
begin
BCallStr4:=BCallStr4+inttohex(ord(rbuf[i]),2); //16进位制按2位一组读出数据
end;
StatusBar1.Panels.Items[0].Text:=Bcallstr4;
BCallNo:=copy(BCallStr4,3,4);
BCallState:=copy(BCallStr4,1,2); //获取呼叫器工作状态标示
mainfrm.ComRevSendSMS; }
end;

procedure TMainFrm.Comm5ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
begin
{ BCallStr5:='';
BCallState:='';
BCallNo:='';
move(buffer^,pchar((@rbuf)^),bufferlength);
for i:=0 to bufferlength-1 do
begin
BCallStr5:=BCallStr5+inttohex(ord(rbuf[i]),2); //16进位制按2位一组读出数据
end;
StatusBar1.Panels.Items[0].Text:=Bcallstr5;
BCallNo:=copy(BCallStr5,3,4);
BCallState:=copy(BCallStr5,1,2); //获取呼叫器工作状态标示
mainfrm.ComRevSendSMS; }
end;

procedure TMainFrm.Comm6ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
begin
{ BCallStr6:='';
BCallState:='';
BCallNo:='';
move(buffer^,pchar((@rbuf)^),bufferlength);
for i:=0 to bufferlength-1 do
begin
BCallStr6:=BCallStr6+inttohex(ord(rbuf[i]),2); //16进位制按2位一组读出数据
end;
StatusBar1.Panels.Items[0].Text:=Bcallstr6;
BCallNo:=copy(BCallStr6,3,4);


BCallState:=copy(BCallStr6,1,2); //获取呼叫器工作状态标示
mainfrm.ComRevSendSMS; }
end;

[解决办法]
我的猜想:虽然你为不同的端口建立了不同的实例,但它们使用的是同一个单元,那么,单元中的全局变量(如收发状态标志变量)就会受各个实例彼此干扰,因而导致通信的不正常。(若我的想法谬误,可以批评,请别扔砖头哦)。

不知道你使用的SPCOMM控件是哪个版本,你尝试看看它的源码,是否会有我以上猜测的可能?或尝试把pas文件改个名字,并把里面注册的类名也改为不同的名字,这样来安装多个不同类名的com口控件,使得每个端口使用不同类名、不同单元建立的实例来通信。若行,就证实我的猜想是对的,不行,也请相告。

另外,当弄通信编程时,别简单地看见代码不符就了事,应该对比清楚,看是收到误码,还是漏码,从而使得容易分析原因所在,你认为是吗?
[解决办法]
你的想法错误,各个实例不会彼此干扰。你的代码其它地方有问题。

我对spcomm非常熟悉。接受参数时一般是将 Buffer: Pointer 移到 byte 或 pchar里面。

你的猜想不对,pas文件改名并注册不同类名也不行,问题不在于此。

抛开你的问题不说,就说代码风格上。你是新手,绝对的新手。6个通讯实例就要写6个ReceiveData吗?写一个足够。就算你用6个,这6个过程中有大量相同的代码,难道你不应该把相同的部分写到一个函数中来重复调用吗?减少代码的冗余和可读性,以全局变量为耻,以局部变量为荣,好好理解这句话吧。
[解决办法]
受教!谢谢

读书人网 >.NET

热点推荐