请问怎么用dephi6.0 来实现对串口的检测(检测到是串口一还是串口二),求源代码,用什么空件来实现,如果实现成功了可以再送分:),谢谢!

解决方案 »

  1.   

    系统里面有哪些串口?
    get names of available comm ports?{ 
      Show the names of available comm ports (com1, com2, ...) 
      Used registry key: hkey_local_machine\hardware\devicemap\serialcomm 
    } uses 
      Registry; procedure TForm1.Button1Click(Sender: TObject); 
    var 
      reg: TRegistry; 
      st: Tstrings; 
      i: Integer; 
    begin 
      reg := TRegistry.Create; 
      try 
        reg.RootKey := HKEY_LOCAL_MACHINE; 
        reg.OpenKey('hardware\devicemap\serialcomm', False); 
        st := TstringList.Create; 
        try 
          reg.GetValueNames(st); 
          for i := 0 to st.Count - 1 do  
            Memo1.Lines.Add(reg.Readstring(st.strings[i])); 
        finally 
          st.Free; 
        end; 
        reg.CloseKey; 
      finally 
        reg.Free; 
      end; 
    end; 
      

  2.   

    ///////////////
    //
    //    (P) Eagle.Yin
    //    Serial port communication unit based on timers
    //
    //    1999/10/02  Mainframe was finished
    //    1999/10/03  Add routine 'Get_Port_Config' for debug
    //                Add Input-Time-Out processing code
    //    1999/10/07  Add error checking when read and write serial port
    //                Add routine 'Set_Port_TimeOut' and delete 'tmOut' parameters in 'Open_Port'
    //                Add routine 'Port_Error_Str' to get text description of port error
    //
    {---$define debugall}
    {---$define debug}unit SerialPort;interface
    uses
       Windows, ExtCtrls;const
       tmInterval  = 50; // timer interval is 50ms
    const
    E_NO_ERROR = 0; // port error codes
       E_OPEN = 1;
       E_GET_STATE = 2;
       E_SET_STATE = 3;
       E_GET_TMO = 4;
       E_SET_TMO = 5;
       E_TIMEOUT   = 6;
       E_READ      = 7;
       E_WRITE     = 8;
       
    const
       InBufferSize= 1024; // size of input buffer
    type
       TInBuffer=  array[0..InBufferSize-1] of byte; // input buffer
       
    type
    TReader = procedure( len:integer; var buf:TInBuffer ) of object; // data reader procedure
       TWatcher = procedure( erCode:integer ) of object; // port exception watcher
    type
       TSerialPort = class( TObject )
       private
          hReader  : TReader; // handle of data reader
          hWatcher : TWatcher; // handle of watcher
          tmReader : TTimer; // port monitor
          tmOutCnt,
          tmOutVal : integer; // time out value, tmOut = TIME_OUT(ms)/tmInterval(ms)
          DataInFlag: boolean; // data flow in flag      procedure   Monitor( Sender:TObject );
       protected
          hPort    : THandle; // handle of serial port
       public
          procedure   Set_Port_TimeOut( tmOut:integer );
          function    Open_Port( PortName:string; BaudRate, ByteSize, StopBits, Parity:integer ):integer;
          procedure   Close_Port;
          function    WriteData( num:integer; var buf ):integer;      function    Get_Port_Config( var BaudRate, ByteSize, StopBits, Parity:integer ):boolean;
          constructor Create( dReader:TReader; dWatcher:TWatcher );
          destructor  Destroy; override;
       end;// TSerialPort   function    Port_Error_Str( eCode:integer ):string;implementation
    uses
       SysUtils, Dialogs;
    //-----------------------------------------------------------------------------------
    var
       Err_Table   : array[0..8] of string = ( // port error message table
          '', // no error
          '打开串行口失败',
          '获取串行口状态失败',
          '设置串行口状态失败',
          '获取串行口超时失败',
          '设置串行口超时失败',
          '串行口无数据输入',
          '读串行口错误',
          '写串行口错误'
       ); // Error string table
    function    Port_Error_Str( eCode:integer ):string;
    //
    // This function return text description for port errors
    //    eCode : Port error code
    //    result: Text description for port error
    //
    begin
       if ( eCode>=0 ) and ( eCode<=8 ) then
          result := Err_Table[eCode] + '(' + inttostr( eCode ) + ')'
       else
          result := '未知串行口错误(' + inttostr( eCode ) + ')';
    end;
    //-----------------------------------------------------------------------------------
    var
       buf      : TInBuffer; // input buffer for monitorprocedure   TSerialPort.Monitor( Sender:TObject );
    //
    // This procedure is the 'OnTimer' event handler of 'tmReader', it reads data from serial port and
    // call 'hReader' if necessary, it also counts timeouts, if timeout occured, it will call the error
    // handler 'hWatcher'
    //
    var
       eCode    : dword;
       cStat    : COMSTAT;
       numRead  : dword;
    begin
       // manipulate serial port
       eCode := 0;
       ClearCommError( hPort, eCode, @cStat );
       repeat
          numRead :=0;
          if not ReadFile( hPort, buf, sizeof( buf ), numRead, nil ) then
          begin
             if Assigned( hWatcher ) then // call read-error handler
                hWatcher( E_READ );
             exit;
          end;{ if }      // count timeout counter
          DataInFlag := numRead >0; // set data flow in flag
          if DataInFlag then // reset time out counter if data in
             tmOutCnt := 0;
          inc( tmOutCnt );
          if tmOutCnt>=tmOutVal then // timeout occured
          begin
             tmOutCnt := 0; // reset time out counter
             if Assigned( hWatcher ) then
                hWatcher( E_TIMEOUT );
          end;{ if }      // pass data to reader
          if Assigned( hReader ) then
             hReader( numRead, buf );
       until ( numReadend;
    //--------------------------------------------------------------------------------------------------
    procedure   TSerialPort.Set_Port_TimeOut( tmOut:integer );
    //
    // This procedure set port timeout value and reset the timeout counter
    //    tmOut : Port timeout value, in milliseconds 
    //
    begin
       tmOutVal := tmOut div tmInterval;
       tmOutCnt := 0;
    end;
      

  3.   

    function    TSerialPort.Open_Port( PortName:string; BaudRate, ByteSize, StopBits, Parity:integer ):integer;
    //
    // Open and config serial port and activate the monitor timer
    //
    function OpenPort:integer;
       begin
        hPort := INVALID_HANDLE_VALUE; // init port handle
          hPort := CreateFile(  pchar( PortName ), // port name
            GENERIC_READ or GENERIC_WRITE, // access mode
                                0, // share mode
                                nil, // security attributes
                                OPEN_EXISTING, // how to create
                                0, // file attributes
                                0 ); // template file      if hPort = INVALID_HANDLE_VALUE then
           result := E_OPEN
          else
           result := E_NO_ERROR;      {$ifdef debug}
             if result<>E_NO_ERROR then
              ShowMessage( 'Can not open port:' + PortName );
          {$endif}
       end;   function ConfigPort:integer;
       var
        commDCB : DCB;
          commTMO : TCOMMTIMEOUTS;
       begin
        if not GetCommState( hPort, CommDCB ) then // can't get port state
          begin
           result := E_GET_STATE;
             CloseHandle( hPort );
             hPort := INVALID_HANDLE_VALUE;
          {$ifdef debug}
            ShowMessage( 'Can not get port state:' + PortName );
           {$endif}
             exit;
          end;{ if }      commDCB.BaudRate := BaudRate; // setup port device control block
          commDCB.ByteSize := ByteSize;
          commDCB.StopBits := StopBits;
          commDCB.Parity := Parity;      if not SetCommState( hPort, commDCB ) then // can't set port state
          begin
           result := E_SET_STATE;
             CloseHandle( hPort );
             hPort := INVALID_HANDLE_VALUE;
          {$ifdef debug}
            ShowMessage( 'Can not set port state:' + PortName );
           {$endif}
             exit;
          end;{ if }      if not GetCommTimeOuts( hPort, commTMO ) then // can't get port time outs
          begin
           result := E_GET_TMO;
             CloseHandle( hPort );
             hPort := INVALID_HANDLE_VALUE;
          {$ifdef debug}
            ShowMessage( 'Can not get port timeouts:' + PortName );
           {$endif}
             exit;
          end;{ if }      with commTMO do // setup port time outs
          begin
        ReadIntervalTimeOut:=MAXDWORD;
           ReadTotalTimeOutMultiplier:=0;
           ReadTotalTimeOutConstant:=0;
          end;{ with }      if not SetCommTimeOuts( hPort, commTMO ) then // can't set port time outs
          begin
           result := E_SET_TMO;
             CloseHandle( hPort );
             hPort := INVALID_HANDLE_VALUE;
          {$ifdef debug}
            ShowMessage( 'Can not set port timeouts:' + PortName );
           {$endif}
             exit;
          end;{ if }      result := E_NO_ERROR; // default result
       end;
    begin
    result := OpenPort; // open port
       if result<>E_NO_ERROR then
          exit;   result := ConfigPort; // config port
       if result<>E_NO_ERROR then
          exit;   PurgeComm( hPort, PURGE_TXABORT + PURGE_RXABORT + PURGE_TXCLEAR + PURGE_RXCLEAR );
       tmReader.Enabled := True; // init monitor timer
    end;procedure   TSerialPort.Close_Port;
    //
    // Close port and deactivate the monitor timer
    //
    begin
       if hPort<>INVALID_HANDLE_VALUE then
       begin
          tmReader.Enabled := False; // disable monitor timer
          
          PurgeComm( hPort, PURGE_TXABORT + PURGE_RXABORT + PURGE_TXCLEAR + PURGE_RXCLEAR );
          CloseHandle( hPort ); // close port
          hPort := INVALID_HANDLE_VALUE;
       end;{ if }
    end;function    TSerialPort.WriteData( num:integer; var buf ):integer;
    var
       eCode : dword;
       cStat : COMSTAT;
    begin
       eCode := 0;
       ClearCommError( hPort, eCode, @cStat );
       result := 0;
       if not WriteFile( hPort, buf,num, dword( result ), nil ) then
       begin
          if Assigned( hWatcher ) then // call write error handler
             hWatcher( E_WRITE );
       end;{ if }
    end;function    TSerialPort.Get_Port_Config( var BaudRate, ByteSize, StopBits, Parity:integer ):boolean;
    //
    // Get current port configuration
    //
    var
       commDCB  : DCB;
    begin
       result := ( hPort<>INVALID_HANDLE_VALUE );
       if result then
       begin
          result := GetCommState( hPort, commDCB );
          if result then
          begin
             BaudRate := commDCB.BaudRate;
             ByteSize := commDCB.ByteSize;
             StopBits := commDCB.StopBits;
             Parity := commDCB.Parity;
          end;{ if }
       end;{ if }
    end;
    //-----------------------------------------------------------------------------------
    constructor TSerialPort.Create( dReader:TReader; dWatcher:TWatcher );
    begin
    inherited Create;   hPort := INVALID_HANDLE_VALUE; // init port handle
       hReader := dReader; // init event handler
       hWatcher := dWatcher; // init watcher handler   tmOutVal := 5*1000; // default time out value is 5s
       DataInFlag := True;   tmReader := TTimer.Create( nil ); // init timer
       with tmReader do
       begin
        Enabled := False;
          Interval := tmInterval;
          OnTimer := Monitor;
       end;{ with }
    end;destructor  TSerialPort.Destroy;
    begin
    hWatcher := nil; // disable event handler
    hReader := nil;
       Close_Port; // close serial port
       tmReader.Destroy; // destroy monitor readerinherited;
    end;end.
    ========================================================
    1.用M$的MSComm控件
    2.用CreateFile打开串口,ReadFile来读,这里有一段我用C Builder写的程序中的一段函数,你看看bool ReceiveByteFromComDev(double TimeReceiveDelay, unsigned char* ByteBuf, HANDLE hCom)
    {
         unsigned long dwNumRead ;
         unsigned long dwNumtoRead ;
         unsigned char TempCommRead[3];
         GetCommTimeouts(hCom,&MyCommTimeouts);
         MyCommTimeouts.ReadIntervalTimeout = TimeReceiveDelay;
         MyCommTimeouts.ReadTotalTimeoutMultiplier = 1;
         MyCommTimeouts.ReadTotalTimeoutConstant = TimeReceiveDelay;
         SetCommTimeouts(hCom ,&MyCommTimeouts );
         dwNumtoRead = 1 ;
         BOOL Fcom=ReadFile(hCom,&TempCommRead,dwNumtoRead ,&dwNumRead,NULL);
         if (Fcom &&  dwNumRead!= 0) {*ByteBuf = TempCommRead[0] ;return true;}
         else return false;
    }
      

  4.   

    我也不懂。不过能否读数据时先用COM1试,如没数据再用COM2试?
      

  5.   

    SpComm
    如果没有数据回传,没有办法获取哪个串口已连线
      

  6.   

    spcomm控件会用吗?
    用它向com1 com2 发送数据(读取数据命令)。用spcomm控件的onreceviedata 事件接受com 口的数据就可以了。