?????????????????????????************
授时卡与系统是串口3通信方式,我们直接用windows api函数。请问那些地方用得不对???下面的给的资料:?????????????????????????************
4.1 端口打开函数
C语言语法: HANDLE CreateFile(
LPCTSTR lpFileName, 
DWORD dwDesiredAccess, 
DWORD dwShareMode, 
LPSECURITY_ATTRIBUTES lpSecurityAttributes, 
DWORD dwCreationDispostion , 
DWORD dwFlagsAndAttributes, 
HANDLE hTemplateFile);
功能:打开TFB013适配卡函数。
输入:lpFileName:时统卡设备名称”COMx”。
返回:时统卡设备句柄
说明:如果打开成功,则返回设备句柄;打开失败返回NULL。
代码示例:下面的代码打开卡。
hDevice=CreateFile(COM3,
  GENERIC_READ | GENERIC_WRITE,
  FILE_SHARE_READ,
  NULL,
  OPEN_EXISTING,
  0,
  NULL);4.4读取时间函数
C语言语法: BOOL ReadFile( 
HANDLE hFile, 
LPVOID lpBuffer, 
DWORD nNumberOfBytesToRead, 
LPDWORD lpNumberOfBytesRead, 
LPOVERLAPPED lpOverlapped);
功能:读取事件信息
输入:hFile 设备句柄;nNumberOfBytesToRead 要读取数据的个数;
输出:lpBuffer 指向返回数据缓冲区的指针;lpNumberOfBytesRead 实际读取数据的个数
返回:读取成功返回TRUE;
说明:如果打开成功则返回非零,失败返回零。
代码示例:
ReadFile(hDevice,buf,n,&nRead,NULL);
读取后buf按次序存放$GPSTM $GPGGA $GPZDA $GPGSV $GPVTG 数据。
注:读取字符长度n最大不大于250。
?????????????????????????************
下面是在delphi7下写的程序:
?????????????????????????************procedure TForm1.Button1Click(Sender: TObject);begin
FHandle := CreateFile(
    'com3',
    GENERIC_READ {or GENERIC_WRITE},
    0,
    nil,
    OPEN_EXISTING,
    0,//FILE_FLAG_OVERLAPPED,
    0);
end;
procedure TForm1.Button1Click(Sender: TObject);begin
FHandle := CreateFile(
    'com3',
    GENERIC_READ {or GENERIC_WRITE},
    0,
    nil,
    OPEN_EXISTING,
    0,
    0);
end;procedure TForm1.Timer1Timer(Sender: TObject);
var
AsyncPtr: PAsync;
BytesTrans: DWORD;
buf:Tchar400;
n:Dword;
nRead:^word;
i:integer;
str:string;
begin
     ReadFile(FHandle, buf, 500, BytesTrans, nil);
     memo1.Text:=buf;
end;?????????????????????????************结果是:下面是正常结果,如果这个程序不能读取正常结果,那么调用dll的程序也不能读取。$GPDTM,W84,,00.0000,N,00.0000,W,,W84*53
$GPGGA,021144,2847.6649,N,10436.2143,E,1,07,02.42,000352.8,M,-032.4,M,,*60
$GPZDA,021145,06,01,2005,+00,00*61
$GPGSV,3,1,09,03,50,042,41,08,14,315,40,11,19,171,00,13,51,245,43*74
$GPGSV,3,2,09,15,13,060,34,16,13,066,33,19,81,077,41,23,39,201,29*74
$GPGSV,3,3,09,27,34,320,40*47
$GPVTG,324.1,T,325.5,M,000.0,N,0000.1,K,A*17?????????????????????????************

解决方案 »

  1.   

    你的代碼似乎有問題, 你用的是阻塞式的讀取方式, 正常應該寫到線程中!可參考 spcomm的源碼來修改你現在的代碼
      

  2.   

    TTimer是不精确,也是非常不可靠的
      

  3.   

    给你个Dll,看看是否能帮你!
    library EasyComm;uses
      SysUtils,Windows;var
      hComm:Thandle;  //通讯句柄
      EnterChar:array[0..0]of Char=(#13);  //回车符{$R *.res}function OpenComm(PortNo,BaudRate:Integer):Integer;stdcall  //打开通讯端口
    var
      DCB:TDCB;
      CommTimeOut:TCommTimeOuts;
    begin
      Result:=0;
      if hComm<>0 then CloseHandle(hComm); //如果已打开则先关闭
      hComm:=CreateFile(Pchar('COM'+IntToStr(PortNo)),  //创建通讯
                        GENERIC_READ or GENERIC_WRITE,  //access (read-write) mode 读和写
                        0,                              //share mode               不共享
                        nil,                            //pointer to security attributes 不被继承
                        OPEN_EXISTING,                  //how to create            存在
                        FILE_ATTRIBUTE_NORMAL,          //file attributes          常规
                        0);                             //handle to file with attributes to copy
      if hComm=Invalid_Handle_Value then
      begin
        CloseHandle(hComm);
        Exit;
      end;
      SetupComm(hComm,4096,4096);               //设置缓冲区大小
      GetCommState(hComm,DCB);                  //取得通讯参数
      DCB.BaudRate:=BaudRate;                   //波特率
      DCB.ByteSize:=8;                          //8数据位
      DCB.Parity:=NoParity;                     //无校验位
      DCB.StopBits:=OneStopBit;                 //1停止位
      if not SetCommState(hComm,DCB) then       //设置通讯参数
      begin
        CloseHandle(hComm);
        Exit;
      end;
      GetCommTimeOuts(hComm,CommTimeOut);             //取得超时参数
      CommTimeOut.ReadIntervalTimeout:=10;            //时间间隔
      CommTimeOut.ReadTotalTimeoutMultiplier:=0;      //时间乘积因子
      CommTimeOut.ReadTotalTimeoutConstant:=500;      //等待时间常量
      if not SetCommTimeOuts(hComm,CommTimeOut) then  //设置超时参数
      begin
        CloseHandle(hComm);
        Exit;
      end;
      Result:=1;
    end;procedure CloseComm();stdcall  //关闭通讯端口
    begin
      CloseHandle(hComm);
      hComm:=0;
    end;function WriteComm(Buf:Pointer;Len:Integer):Integer;stdcall  //向端口发送数据,返回实际发送的字符数
    var
      Sendl1,Sendl2:Dword;
    begin
      Result:=0;
      Sendl1:=Len;
      Sendl2:=0;
      if WriteFile(hComm,Buf^,Sendl1,Sendl2,nil) then
        Result:=Sendl2;
    end;function ReadComm(Buf:Pointer;Len:Integer):Integer;stdcall  //在端口接收数据,返回实际收到的字符数
    var
      Receivel1,Receivel2:Dword;
    begin
      Result:=0;
      Receivel1:=Len;
      Receivel2:=0;
      if ReadFile(hComm,Buf^,Receivel1,Receivel2,nil) then
        Result:=Receivel2;
    end;function Dial(PhoneNum:Pchar):Integer;stdcall  //拨号,建立连接
    var
      Len:Integer;
    begin
      Result:=0;
      if WriteComm(Pchar('ATDT'),4)<>4 then  Exit;
      len:=StrLen(PhoneNum);
      if Len=0 then Exit;
      if WriteComm(PhoneNum,len)<>len then  Exit;
      Sleep(2);
      if WriteComm(@EnterChar,1)<>1 then  Exit;
      Result:=1;
    end;procedure HangUp();stdcall  //挂断连接
    begin
      WriteComm(Pchar('+++'),3);
      Sleep(500);
      WriteComm(Pchar('ATH0'),4);
      Sleep(2);
      WriteComm(@EnterChar,1);
    end;function SetAnswer(Rings:Byte):Integer;stdcall  //设置自动应答
    var
      RingsStr:string;
      StrLen:Integer;
    begin
      Result:=0;
      RingsStr:=IntToStr(Rings);
      StrLen:=Length(RingsStr);
      if WriteComm(Pchar('ATS0='+RingsStr),5+StrLen)<>5+StrLen then  Exit;
      Sleep(2);
      if WriteComm(@EnterChar,1)<>1 then  Exit;
      Result:=1;
    end;exports
      OpenComm index 1 name 'OpenComm',
      CloseComm index 2 name 'CloseComm',
      WriteComm index 3 name 'WriteComm',
      ReadComm index 4 name 'ReadComm',
      Dial index 5 name 'Dial',
      HangUp index 6 name 'HangUp',
      SetAnswer index 7 name 'SetAnswer';
    begin
    end.