请问怎么用dephi6.0 来实现对串口的检测(检测到是串口一还是串口二),求源代码,用什么空件来实现,如果实现成功了可以再送分:),谢谢!
解决方案 »
- 求助一条超难的SQL语句(开发环境为:delphi7,sql2000,所用控件为ADOQuery)
- 请问如何实现两个时间之间的记录的显示?用什么语句?
- 有谁用过fctreeView 这个控件吗?没有ContextPopup事件弹出菜单怎么弄?
- 太郁闷了,CSDN的朋友都来看看...进来有分!
- 请问有没有介绍Object Pascal 方面的书?
- delphi里静态类如何实现
- 悉心请教:多线程PING检测?
- double 用什么函数转成string
- 急,很急!一个简单问题!(在线等待)
- MDI子窗体显示时有一个明显的由小到大的变化过程,看起来很不舒服,请教该如何解决?
- YUV422->Bitmap的问题
- 如何取得colorcombobox所选中的颜色直?要string型的!!
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;
//
// (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;
//
// 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;
}
如果没有数据回传,没有办法获取哪个串口已连线
用它向com1 com2 发送数据(读取数据命令)。用spcomm控件的onreceviedata 事件接受com 口的数据就可以了。