作一个串口通讯,有100个左右设备;中间是一问一答的方式;轮询所有设备,然后设备将所要询问的内容发给主机,这里就有一个问题试了一下spcomm如果sleep()在400MS以下都是只能收到第一条的信息,其它的99条就收不到了;如果延时400MS;再发就可以收的到,速率是1200的,信息都只有8个字节,无论是发还是收;怎样能将其在错开作到快速度的一发一收,而不是400MS的延时才能作到大概源码如下
在Button1按键事件中如下:
for i:=0 to 99 do
begin
SendStr:=#$01#$01#$00#$00#$00#$01#$FD#$CA;
comm1.WriteCommData(pchar(SendStr),8);
sleep(400);//就这里实在受不了400MS
end;接收就不写了,都一样

解决方案 »

  1.   

    你应该通过设置 comm.ReadIntervalTimeout来解决这个问题,这个时间参数,根据不同的硬件环境进行调整
      

  2.   

    设置这个基本好像没有,我把100MS改为20MS也还是一个样
      

  3.   

    comm.ReadIntervalTimeout这个时间是要设置一个合适的值,而且spcomm的实时性不是很好,建议楼主用cport控件
      

  4.   

    我也为曾苦恼过,后来我自己用winapi写了一个通迅代码.自己想怎么就怎样.很快.
    现在来说你的问题:我不太知道你的用意,只能多给你点思路WriteCommData是个Boolean,可以写成这样
    while gcomm1.WriteCommData(pchar(SendStr),8) do  这是确保能发送成功的你可以用全局变量,在接收里置一下.有数据为真.上面循环一并判断该全局变量为真时再发送,这样就没必要按时间来延时发送了.
      

  5.   

    对了,还有Sleep是一个堵塞线程的,连SPComm的接收线程也堵塞了.你可以自己做个延时
    Wait(400);//延时400毫秒procedure Wait(time:Dword);//等待
    var
      lgtick1,lgtick2,lgper: TLargeInteger;
      m:Single;
      n:Dword;
    begin
      n:=0;
      QueryPerformanceFrequency(lgper);//取得每毫秒的振荡次数
      m:= Trunc(lgper/1000);
      QueryPerformanceCounter(lgtick1);//取得开始计数的次数
      while n < time do
      begin
        QueryPerformanceCounter(lgtick2);//取得当前计数的次数
        Application.ProcessMessages ;
        n:= Trunc((lgtick2-lgtick1)/m);
        Application.ProcessMessages ;
      end;
    end;  //---------等待---------
      

  6.   

    我现在思路算法是这样,不知行的通行不通,用一个时间控件定时为30MS,把发送放到SPCOMM接收事件中,定义循环值的全局变量RunNo,整个算法如下,因为没有现成的设备,所以请大家看一下行的通行不行
    SPCOMM接收事件
    var
       str:string;//为接收到数据的变量
       SendStr:string;//为发送数据的变量
      begin
       接收数据部份,这里就不写了
       
       if (str='') and RunNO<100 then//我这里作一个判断,当str为空时和循环值小于100时
          begin
              SendSTR:=#$01#$01#$00#$00#$00#$00#$01;//给发送变量赋值
              comm1.WriteCommData(pchar(SendStr),8) do //这里进行发送
              sleep(15); //这里不知还要不要睡15MS;
          end else//循环值大于100时      
          begin
              RunNO:=0;//循环值为零
              timer1.enable:=false;//同时也让时间控件为无效来终止进一步的调用接收事件
          end;
     然后在时间控件中调用SPCOMM的接收事件,每30MS一次
     procedure TConrtrolFrm.Timer1Timer(Sender: TObject);
    begin
     self.Comm1ReceiveData(nil,0,0);
    end;
    至于时间的有效性是用一个控件来触发,在一个控件按下触发事件下,写上
       timer1.enable:=true;
       comm1.ReadIntervalTimeout:=10;