奇怪的串口转换通信问题(Comport控件),望有哪位高手能够迷津谢谢!!!!!!!!! (200分)

  • 主题发起人 主题发起人 finewei
  • 开始时间 开始时间
F

finewei

Unregistered / Unconfirmed
GUEST, unregistred user!
问题如下:
使用Comport控件来发送和接收数据,接收部分使用线程处理,使用串口1程序都能发收
都正常,现改用串口2和其它串口都会出现只能发送,不能接收数据的情况(串口和通信线
均没问题,其它关于串口的设置和程序都没有动过),我单步跟踪后发现OnRxChar数据过来
这时我创建线程对接收的问题进行处理(线程使用了同步),奇怪的是我单步跟踪都对的,
直接运行又收不到数据,我怀疑是延时的问题,我加上SLEEP延时发现是可接收到数据,但
也会有数据丢失,而且加了延时整个软件运行就变得很慢,如果是延时的问题,为什么串
口1不加延时也是正常接收数据呢?还有怎么解决线程内加延时软件运行变慢的问题。

 
comport 我没有用过,你可以试试使用spcomm
另外,你的线程可能存在问题,因没有见到程序,也只能说这么多
 
同意wrf的看法,spcomm不错
 
在串口通讯问题上,有关DELPHI 控件SPCOMM;
另一个是MSCOM,在VB 中的一个ACTIVE 控件,操作串口很方便;
其它方法,你也可以API函数;
你可以看看COM2 口的参数否正确;
 
先谢谢以上三位热心参与!
经过我反复测试以下几个问题可以明确:
1、我去掉线程已经试过了,问题仍然存在说明不是线程的问题
2、我把串口控件每一次触发的字符串马上显示出来,发现问题是:
串口1是一串一串字符触发的(基本上是14个字符触发一次),
而串口2是一个字符一个字符触发的(问题的关键所在,为什么会出现这种情况????)
暂时有解决的办法是:加延时,但不是很理想。
 
finewei:
能不能给小弟一个关于串口编程的历程?谢谢
newhzh@163.com
 
是你的控件在处理线程上有问题,换AsyncFree这个比SPCOMM还好
 
我一直用Comport组件,发现这个组件挺好用的。
对于楼主的问题,我一般情况下是这样解决的。
用一个全局变量来记录串口接收的数据Count和。
用一个全局变量来记录串口接收的String值。(累加)
当count达到我的预定值时就调用处理过程。
ComPort是多线程的。在Onrxchar中调用一些VCL有时候会出错。这样的情况我遇到多次。
一般情况下,我把调用都改到其他线程里。并等待该线程结束。
 
1、我去掉线程已经试过了,问题仍然存在说明不是线程的问题
2、我把串口控件每一次触发的字符串马上显示出来,发现问题是:
串口1是一串一串字符触发的(基本上是14个字符触发一次),
而串口2是一个字符一个字符触发的(问题的关键所在,为什么会出现这种情况????)
暂时有解决的办法是:加延时,但不是很理想。

是不是数据初始化的协议不同...
如长度什么的...
 
检测接收个数.
最好不用控件.
 
每个ComPort连同接收缓冲区封装到一个线程,
线程中检测接收到的字符数是否达到可以处理的程度,如果是,则处理完成后,通知主线程。
我用这种结构实现了48个COM口同时通讯,每口端口都正常,每天24hour运行一年多了。
 
to apw
可以告诉你的QQ或MSN吗,你的经验对我来说很重要,希望能进一步探讨这个问题。
 
comport要比spcomm好使得多,至少实时性就强上10倍。
没看到楼主的源代码,不知道你处理接收数据是否有判断,我开始用comport时发现它每次
14个字符触发一次接收事件,而我要接收的一帧完整数据是82个字符,因此我在每帧的前后个加了开始码和结束码,共84个字符,当Count值大于84我才处理,程序片断如下:
procedure TFCOMM.ComPortRxChar(Sender: TObject;
Count: Integer);
var
ReceiveData:TDateRec;
p:Pbyte;
Block : array[0..85] of Char;
begin
if (not Ready) then
begin
ComPort.Read(p,1);
//开始码为$7FFE,接收时先收的是$FE
move(p, SecondByte,1);
if SecondByte = $FE then
//如果收到的字节是$FE,那就看看下一个是不是$7F
begin
FirstByte := SecondByte;
ComPort.Read(p,1);;
move(p, SecondByte,1);
end;
end;

if (FirstByte = $FE) and (SecondByte = $7F) then
Ready := True;
if Ready and (count>=84) then
begin
。。。。
end;
end;
 
后退
顶部