DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: hcwong1993
今日帖子: 36
在线用户: 19
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 qingyun (qingyun) ★☆☆☆☆ -
盒子活跃会员
2003/9/30 13:35:58
标题:
 如何控制串口(Rs-232口)通讯中发送报文和接收报文间的时间间隔? 浏览:1616
加入我的收藏
楼主: 比如我用pc机和终端设备通过RS-232进行通信,通信线就用了2、3、5这三个引脚。属于那种最简单的通讯方式。
 现在我有一个疑问:

比如pc机发送  10 5B 01 5C 16  给终端
终端收到后,再回复给pc机
PC 机接收到  68 BE BE 68 88 01 02 74 05 01 0D 00 8D 00 02 00 10 3F 00 08 11 00 BF 01 3F 00 C0 00 09 10 01 3F 0B 00 00 BF 10 04 01 00 01 00 00 00 02 00 00 00 00 00 01 00 00 01 00 00 01 00 00 00 01 00 01 00 00 00 00 01 01 00 00 00 00 00 01 00 01 00 00 00 02 00 00 00 00 00 01 00 00 01 00 00 01 00 00 00 01 00 01 00 00 00 00 01 01 00 00 00 00 00 01 00 01 00 00 00 02 00 00 00 00 00 01 00 00 01 00 00 01 00 00 00 01 00 01 00 00 00 00 01 01 00 00 00 00 00 01 00 01 00 00 00 02 00 00 00 00 00 01 00 00 01 00 00 01 00 00 00 01 00 01 00 00 00 00 01 01 00 00 00 00 00 01 00 01 00 00 00 02 00 00 00 00 00 2F 16 

现在我发现一个问题,就是
因为接收的抱文有点长
如果我这样写:
                  发送报文('10 5B 01 5C 16 ');
                 memo1.text:=接收报文;
那么接收到的可能是 68 BE BE 68 88 01 02 74 05 01 0D 00 8D 00 02 00 10 3F 00 08 11 00 BF 01 3F 00 C0 00 09 10 01 3F 0B 00 00 BF 10 04 01 00 01 00 00 00 02 00 00 00 00 00 01 00 
也就是说我接受的时候,终端正在发送报文给pc机,如果我立即收报文,只能收到一截,而不是全部。

所以我改写了一下程序

                  发送报文('10 5B 01 5C 16 ');
                  sleep(500);
                 memo1.text:=接收报文;
这样接收到的报文就全了,但是延时500ms是不是太浪费了,而且如果终端回复给pc机报文太长,也许延时500ms也不一定够。

所以我想到了另一种方法

    发送报文('10 5B 01 5C 16 ');
      sleep(20);
  看看接收缓冲区的报文长度;
      sleep(20);
   再看看接收缓冲区的报文长度;   
  比较这两次报文长度是否相等,如果相等,说明收全了,这时就读出缓冲区的报文,清空缓冲区;如果不等,说明终端正在发报文,还没有发完,再看看接收缓冲区的报文长度,继续比较,如此循环,只到最后两次收到的报文长度相等了,才读出缓冲区的报文,清空缓冲区;

  对应的代码:
timedelay(20);
 ClearCommError(hCommHandle,dwError,@CS);  //取得状态
 comp:=cs.cbInQue;
 for i:=1 to 50 do
 begin
   timedelay(20);
   ClearCommError(hCommHandle,dwError,@CS);  //取得状态
   if  (comp=cs.cbInQue) and (cs.cbInQue>1) then break;//报文收全了
end; 
RecieveCount:=cs.cbInQue;
if cs.cbInQue >2048  then
begin
  PurgeComm(hCommHandle, PURGE_RXCLEAR);
   RecieveCount:=0;
  // 清除COM 数据
  exit;
end;
try
   ReadFile(hCommHandle, ByteArray,cs.cbInQue,nBytesRead,nil); // 接收COM 的数据
except

end;

不过我认为我这种方法不好 ,我看到好多串口调试软件都是把发送和接收分开处理的,因为本来Rs-232就是全双工方式,好象都用到了线程,
而且我发现好象没有报文只收到一半的情况,我觉得很奇怪,因为它们在读取缓冲区数据的时候,怎么知道此时终端发给pc机的数据已经发完了,
万一正在发送,那不是也有可能只收到一截吗?

----------------------------------------------
青云论坛
作者:
男 rat2003 ( ) ★☆☆☆☆ -
盒子活跃会员
2004/2/26 9:21:46
1楼: 一句话:什么时候数据发完,要你的程序判断。
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行62.5毫秒 RSS