我在开发手机管理程序时也说遇到过类似的问题,最后我只用WIN API解决了这个问题:下面给出单元文件,有关与手机通讯的源代码请在http://tansuo.51.net上下载unit ComPort;interface uses Windows,SysUtils;type ECommsError = class( Exception );var iComNum : integer = 2; // iOldComOpen : integer = 0; iComBaud : integer = 115200; // iOldComBaud : integer = 0; hCom : THandle=INVALID_HANDLE_VALUE; ComTimeouts : TCommTimeouts; txLen, rxLen : Dword; FlgOvrlp : boolean = True; COMwr : OVERLAPPED; COMrd : OVERLAPPED; COMst : COMSTAT; DCB : TDCB; { DCB结构 : 0 DWORD fBinary: 1; // binary mode, no EOF check 1 DWORD fParity: 1; // enable parity checking 2 DWORD fOutxCtsFlow:1; // CTS output flow control 3 DWORD fOutxDsrFlow:1; // DSR output flow control 4..5 DWORD fDtrControl:2; // DTR flow control type 6 DWORD fDsrSensitivity:1; // DSR sensitivity 7 DWORD fTXContinueOnXoff:1; // XOFF continues Tx 8 DWORD fOutX: 1; // XON/XOFF out flow control 9 DWORD fInX: 1; // XON/XOFF in flow control 10 DWORD fErrorChar: 1; // enable error replacement 11 DWORD fNull: 1; // enable null stripping 12..13 DWORD fRtsControl:2; // RTS flow control 14 DWORD fAbortOnError:1; // abort reads/writes on error 15..31 DWORD fDummy2:17; // reserved}function OpenCom(Mode:boolean) : boolean; procedure CloseCom; function GetComDCB : boolean; function SetComDCB : boolean; function GetComTimeouts : boolean; function SetComTimeouts : boolean; function SetComRxTimeouts(NewIntervalTimeout,NewTimeoutMultiplier,NewTimeoutConstant:dword) : boolean; function ReadCom(Buf:Pointer; BufLen:Dword) : boolean; function WriteCom(Buf:Pointer; BufLen:Dword) : boolean; function EscapeComFunction(dwFunc:Dword) : boolean; function GetComModemStatus : DWORD; function GetComStat : boolean; function PurgeCom(mode:Dword): boolean; // 清空读写缓冲区中的数据 function WriteComStr(S: String): boolean; function ChangeComSpeed(Baud:integer) : boolean;implementationfunction OpenCom(Mode:boolean) : boolean; var dw : dword; begin result:=FALSE; if hCom<>INVALID_HANDLE_VALUE then CloseCom; if FlgOvrlp then // 同步、异步通讯模式 dw:=FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED else dw:= 0; // 同步 hCom:=CreateFile(PChar('\\.\COM'+IntToStr(iComNum)),GENERIC_READ or GENERIC_WRITE,0,nil,OPEN_EXISTING,dw,0); if hCom = INVALID_HANDLE_VALUE then raise ECommsError.Create( '串口打开失败.' ) else begin if GetFileType( hCom ) <> FILE_TYPE_CHAR then begin CloseHandle( hCom ); raise ECommsError.Create( '文件句柄不是通信句柄. ' ) end; if not SetupComm( hCom, 8192, 8192 ) then // Rd , Wr begin CloseHandle( hCom ); raise ECommsError.Create( '串口缓冲设置失败.' ) end; if GetComDCB then begin if Mode then DCB.Flags := (DCB.Flags and $ffff8000) or $0001 else DCB.Flags := (DCB.Flags and $ffff8000) or $0011; //$1011; DCB.ByteSize := 8; DCB.Parity := 0; DCB.StopBits := 0; DCB.BaudRate := iComBaud; if SetComDCB then begin ComTimeouts.ReadIntervalTimeout:=20; //0 ComTimeouts.ReadTotalTimeoutMultiplier:=1; //0 ComTimeouts.ReadTotalTimeoutConstant:=2000; //200 ComTimeouts.WriteTotalTimeoutMultiplier:=1;//MAXDWORD; ComTimeouts.WriteTotalTimeoutConstant:=2000;//MAXDWORD; if SetComTimeouts then begin iOldComOpen:=iComNum; iOldComBaud:=iComBaud; if Mode then begin sleep(75); EscapeComFunction(SETRTS); // 发送RTS信号 sleep(25); EscapeComFunction(SETDTR); // 发送DTR信号 end else begin sleep(75); EscapeComFunction(SETRTS); // 发送RTS信号 end; result := TRUE; end; end; end; end; end;procedure CloseCom; var x: THandle; begin if hCom<>INVALID_HANDLE_VALUE then begin x:=hCom; hCom:=INVALID_HANDLE_VALUE; CloseHandle(x); end; iOldComOpen:=0; end;function GetComDCB : boolean; begin result := FALSE; if hCom<>INVALID_HANDLE_VALUE then result := GetCommState(hCom,DCB); end;
function SetComDCB : boolean; begin result:=FALSE; if hCom<>INVALID_HANDLE_VALUE then result := SetCommState(hCom,DCB); end;function ChangeComSpeed(Baud:integer) : boolean; var save_baud : integer; begin result:=FALSE; save_baud:=dcb.BaudRate; if hCom<>INVALID_HANDLE_VALUE then begin if GetComDCB then begin if dcb.BaudRate<>Dword(Baud) then begin dcb.BaudRate:=Baud; result := SetCommState(hCom,DCB); EscapeComFunction(SETRTS); EscapeComFunction(SETDTR); if not result then begin dcb.BaudRate:=save_baud; SetCommState(hCom,DCB); EscapeComFunction(SETRTS); EscapeComFunction(SETDTR); end; end; end; end; end;function GetComTimeouts : boolean; begin result:=FALSE; if hCom<>INVALID_HANDLE_VALUE then result := GetCommTimeouts(hCom,ComTimeouts); end;function SetComTimeouts : boolean; begin result:=FALSE; if hCom<>INVALID_HANDLE_VALUE then if SetCommTimeouts(hCom,ComTimeouts) then result:=TRUE; end;function SetComRxTimeouts(NewIntervalTimeout,NewTimeoutMultiplier,NewTimeoutConstant:dword) : boolean; begin result:=FALSE; if (ComTimeouts.ReadIntervalTimeout<>NewIntervalTimeout) or (ComTimeouts.ReadTotalTimeoutMultiplier<>NewTimeoutMultiplier) or (ComTimeouts.ReadTotalTimeoutConstant<>NewTimeoutConstant) then begin ComTimeouts.ReadIntervalTimeout:=NewIntervalTimeout; ComTimeouts.ReadTotalTimeoutMultiplier:=NewTimeoutMultiplier; ComTimeouts.ReadTotalTimeoutConstant:=NewTimeoutConstant; if hCom<>INVALID_HANDLE_VALUE then if SetCommTimeouts(hCom,ComTimeouts) then result:=TRUE; end else result:=TRUE; end;function GetComStat : boolean; var dErr : DWORD; begin result:=FALSE; dErr := 0; if hCom<>INVALID_HANDLE_VALUE then begin GetCommState( hCom, dcb ); if ClearCommError(hCom,dErr,@COMst) then begin // size Rx buff := COMst.cbInQue; Result := True; end; end; end;function ReadCom(Buf:Pointer; BufLen :Dword) : boolean; var dErr: Dword; begin result := False; if (hCom<>INVALID_HANDLE_VALUE)and(Buf<>Nil)and(BufLen<>0) then begin rxlen:=0; if FlgOvrlp then begin COMrd.hEvent:=CreateEvent(Nil,TRUE,FALSE,Nil); if not ReadFile(hCom,Buf^,BufLen,rxLen,@COMrd) then begin if not GetOverlappedResult(hCom,COMrd,rxLen,True) then begin end; end; // ResetEvent(COMrd.hEvent); CloseHandle(COMrd.hEvent); end else begin if not ReadFile(hCom,Buf^,BufLen,rxLen,Nil) then begin // ClearCommError(hCom,dErr,Nil); // exit; end; end; if rxLen = BufLen then result := True else ClearCommError(hCom,dErr,Nil); end; end;function WriteCom(Buf:Pointer; BufLen:Dword) : boolean; Var dErr: Dword; begin result:=FALSE; if (hCom<>INVALID_HANDLE_VALUE)and(Buf<>Nil)and(BufLen<>0) then begin txLen:=0; if FlgOvrlp then begin COMwr.hEvent:=CreateEvent(Nil,TRUE,FALSE,Nil); if not WriteFile(hCom,Buf^,BufLen,txLen,@COMwr) then begin if not GetOverlappedResult(hCom,COMwr,txLen,True) then begin end; // ClearCommError(hCom,dErr,Nil); end; // ResetEvent(COMwr.hEvent); CloseHandle(COMwr.hEvent); end else begin if not WriteFile(hCom,Buf^,BufLen,txLen,Nil) then begin // ClearCommError(hCom,dErr,Nil); // exit; end; end; if txLen = BufLen then result:=TRUE else ClearCommError(hCom,dErr,Nil); //PurgeComm(hCom, PURGE_TXABORT + PURGE_TXCLEAR); end; end;function WriteComStr(S: String): boolean; begin Result:=WriteCom(@S[1],Length(S)); end;function PurgeCom(mode:Dword): boolean; //function begin result := PurgeComm(hCom,mode); // 清空读写缓冲区中的数据 end;function EscapeComFunction(dwFunc:Dword):boolean; begin result:=FALSE; if hCom<>INVALID_HANDLE_VALUE then result := EscapeCommFunction(hCom,dwFunc); end; ////////////////////////////////////////////////////////// // FUNCTION: GetComModemStatus // // PURPOSE: Read the state of modem input pin right now // // PARAMETERS: // none // // RETURN VALUE: // // A DWORD variable containing one or more of following codes: // // Value Meaning // ---------- ----------------------------------------------------------- // MS_CTS_ON The CTS (clear-to-send) signal is on. // MS_DSR_ON The DSR (data-set-ready) signal is on. // MS_RING_ON The ring indicator signal is on. // MS_RLSD_ON The RLSD (receive-line-signal-detect) signal is on. // // If this comm have bad handle or not yet opened, the return value is 0 // // COMMENTS: // // This member function calls GetCommModemStatus and return its value. // Before calling this member function, you must have a successful // 'StartOpen' call. // // function GetComModemStatus : DWORD; var dwModemState : DWORD; begin if hCom<>INVALID_HANDLE_VALUE then if not GetCommModemStatus( hCom, dwModemState ) then Result := 0 else Result := dwModemState end;end.
因为是第三代语言.第一代是 机器码 第二代是 汇编 第三代是 C 第四代是 Delphi胡诌,让什么老教授晕一下.
uses Windows,SysUtils;type
ECommsError = class( Exception );var
iComNum : integer = 2; //
iOldComOpen : integer = 0;
iComBaud : integer = 115200; //
iOldComBaud : integer = 0;
hCom : THandle=INVALID_HANDLE_VALUE;
ComTimeouts : TCommTimeouts;
txLen, rxLen : Dword;
FlgOvrlp : boolean = True;
COMwr : OVERLAPPED;
COMrd : OVERLAPPED;
COMst : COMSTAT;
DCB : TDCB;
{ DCB结构 :
0 DWORD fBinary: 1; // binary mode, no EOF check
1 DWORD fParity: 1; // enable parity checking
2 DWORD fOutxCtsFlow:1; // CTS output flow control
3 DWORD fOutxDsrFlow:1; // DSR output flow control
4..5 DWORD fDtrControl:2; // DTR flow control type
6 DWORD fDsrSensitivity:1; // DSR sensitivity
7 DWORD fTXContinueOnXoff:1; // XOFF continues Tx
8 DWORD fOutX: 1; // XON/XOFF out flow control
9 DWORD fInX: 1; // XON/XOFF in flow control
10 DWORD fErrorChar: 1; // enable error replacement
11 DWORD fNull: 1; // enable null stripping
12..13 DWORD fRtsControl:2; // RTS flow control
14 DWORD fAbortOnError:1; // abort reads/writes on error
15..31 DWORD fDummy2:17; // reserved}function OpenCom(Mode:boolean) : boolean;
procedure CloseCom;
function GetComDCB : boolean;
function SetComDCB : boolean;
function GetComTimeouts : boolean;
function SetComTimeouts : boolean;
function SetComRxTimeouts(NewIntervalTimeout,NewTimeoutMultiplier,NewTimeoutConstant:dword) : boolean;
function ReadCom(Buf:Pointer; BufLen:Dword) : boolean;
function WriteCom(Buf:Pointer; BufLen:Dword) : boolean;
function EscapeComFunction(dwFunc:Dword) : boolean;
function GetComModemStatus : DWORD;
function GetComStat : boolean;
function PurgeCom(mode:Dword): boolean; // 清空读写缓冲区中的数据
function WriteComStr(S: String): boolean;
function ChangeComSpeed(Baud:integer) : boolean;implementationfunction OpenCom(Mode:boolean) : boolean;
var
dw : dword;
begin
result:=FALSE;
if hCom<>INVALID_HANDLE_VALUE then
CloseCom; if FlgOvrlp then // 同步、异步通讯模式
dw:=FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED
else
dw:= 0; // 同步 hCom:=CreateFile(PChar('\\.\COM'+IntToStr(iComNum)),GENERIC_READ or GENERIC_WRITE,0,nil,OPEN_EXISTING,dw,0);
if hCom = INVALID_HANDLE_VALUE then
raise ECommsError.Create( '串口打开失败.' )
else
begin
if GetFileType( hCom ) <> FILE_TYPE_CHAR then
begin
CloseHandle( hCom );
raise ECommsError.Create( '文件句柄不是通信句柄. ' )
end; if not SetupComm( hCom, 8192, 8192 ) then // Rd , Wr
begin
CloseHandle( hCom );
raise ECommsError.Create( '串口缓冲设置失败.' )
end; if GetComDCB then
begin
if Mode then
DCB.Flags := (DCB.Flags and $ffff8000) or $0001
else
DCB.Flags := (DCB.Flags and $ffff8000) or $0011; //$1011; DCB.ByteSize := 8;
DCB.Parity := 0;
DCB.StopBits := 0;
DCB.BaudRate := iComBaud;
if SetComDCB then
begin
ComTimeouts.ReadIntervalTimeout:=20; //0
ComTimeouts.ReadTotalTimeoutMultiplier:=1; //0
ComTimeouts.ReadTotalTimeoutConstant:=2000; //200
ComTimeouts.WriteTotalTimeoutMultiplier:=1;//MAXDWORD;
ComTimeouts.WriteTotalTimeoutConstant:=2000;//MAXDWORD;
if SetComTimeouts then
begin
iOldComOpen:=iComNum;
iOldComBaud:=iComBaud;
if Mode then
begin
sleep(75);
EscapeComFunction(SETRTS); // 发送RTS信号
sleep(25);
EscapeComFunction(SETDTR); // 发送DTR信号
end
else
begin
sleep(75);
EscapeComFunction(SETRTS); // 发送RTS信号
end;
result := TRUE;
end;
end;
end;
end;
end;procedure CloseCom;
var
x: THandle;
begin
if hCom<>INVALID_HANDLE_VALUE then
begin
x:=hCom;
hCom:=INVALID_HANDLE_VALUE;
CloseHandle(x);
end;
iOldComOpen:=0;
end;function GetComDCB : boolean;
begin
result := FALSE;
if hCom<>INVALID_HANDLE_VALUE then
result := GetCommState(hCom,DCB);
end;
begin
result:=FALSE;
if hCom<>INVALID_HANDLE_VALUE then
result := SetCommState(hCom,DCB);
end;function ChangeComSpeed(Baud:integer) : boolean;
var
save_baud : integer;
begin
result:=FALSE;
save_baud:=dcb.BaudRate;
if hCom<>INVALID_HANDLE_VALUE then
begin
if GetComDCB then
begin
if dcb.BaudRate<>Dword(Baud) then
begin
dcb.BaudRate:=Baud;
result := SetCommState(hCom,DCB);
EscapeComFunction(SETRTS);
EscapeComFunction(SETDTR);
if not result then
begin
dcb.BaudRate:=save_baud;
SetCommState(hCom,DCB);
EscapeComFunction(SETRTS);
EscapeComFunction(SETDTR);
end;
end;
end;
end;
end;function GetComTimeouts : boolean;
begin
result:=FALSE;
if hCom<>INVALID_HANDLE_VALUE then
result := GetCommTimeouts(hCom,ComTimeouts);
end;function SetComTimeouts : boolean;
begin
result:=FALSE;
if hCom<>INVALID_HANDLE_VALUE then
if SetCommTimeouts(hCom,ComTimeouts) then result:=TRUE;
end;function SetComRxTimeouts(NewIntervalTimeout,NewTimeoutMultiplier,NewTimeoutConstant:dword) : boolean;
begin
result:=FALSE;
if (ComTimeouts.ReadIntervalTimeout<>NewIntervalTimeout)
or (ComTimeouts.ReadTotalTimeoutMultiplier<>NewTimeoutMultiplier)
or (ComTimeouts.ReadTotalTimeoutConstant<>NewTimeoutConstant)
then
begin
ComTimeouts.ReadIntervalTimeout:=NewIntervalTimeout;
ComTimeouts.ReadTotalTimeoutMultiplier:=NewTimeoutMultiplier;
ComTimeouts.ReadTotalTimeoutConstant:=NewTimeoutConstant;
if hCom<>INVALID_HANDLE_VALUE then
if SetCommTimeouts(hCom,ComTimeouts) then
result:=TRUE;
end
else
result:=TRUE;
end;function GetComStat : boolean;
var
dErr : DWORD;
begin
result:=FALSE;
dErr := 0;
if hCom<>INVALID_HANDLE_VALUE then
begin
GetCommState( hCom, dcb );
if ClearCommError(hCom,dErr,@COMst) then
begin
// size Rx buff := COMst.cbInQue;
Result := True;
end;
end;
end;function ReadCom(Buf:Pointer; BufLen :Dword) : boolean;
var
dErr: Dword;
begin
result := False;
if (hCom<>INVALID_HANDLE_VALUE)and(Buf<>Nil)and(BufLen<>0) then begin
rxlen:=0;
if FlgOvrlp then begin
COMrd.hEvent:=CreateEvent(Nil,TRUE,FALSE,Nil);
if not ReadFile(hCom,Buf^,BufLen,rxLen,@COMrd) then begin
if not GetOverlappedResult(hCom,COMrd,rxLen,True) then begin
end;
end;
// ResetEvent(COMrd.hEvent);
CloseHandle(COMrd.hEvent);
end
else begin
if not ReadFile(hCom,Buf^,BufLen,rxLen,Nil) then begin
// ClearCommError(hCom,dErr,Nil);
// exit;
end;
end;
if rxLen = BufLen then result := True
else ClearCommError(hCom,dErr,Nil);
end;
end;function WriteCom(Buf:Pointer; BufLen:Dword) : boolean;
Var
dErr: Dword;
begin
result:=FALSE;
if (hCom<>INVALID_HANDLE_VALUE)and(Buf<>Nil)and(BufLen<>0) then begin
txLen:=0;
if FlgOvrlp then begin
COMwr.hEvent:=CreateEvent(Nil,TRUE,FALSE,Nil);
if not WriteFile(hCom,Buf^,BufLen,txLen,@COMwr) then begin
if not GetOverlappedResult(hCom,COMwr,txLen,True) then begin
end;
// ClearCommError(hCom,dErr,Nil);
end;
// ResetEvent(COMwr.hEvent);
CloseHandle(COMwr.hEvent);
end
else begin
if not WriteFile(hCom,Buf^,BufLen,txLen,Nil) then begin
// ClearCommError(hCom,dErr,Nil);
// exit;
end;
end;
if txLen = BufLen then result:=TRUE
else ClearCommError(hCom,dErr,Nil);
//PurgeComm(hCom, PURGE_TXABORT + PURGE_TXCLEAR);
end;
end;function WriteComStr(S: String): boolean;
begin
Result:=WriteCom(@S[1],Length(S));
end;function PurgeCom(mode:Dword): boolean; //function
begin
result := PurgeComm(hCom,mode); // 清空读写缓冲区中的数据
end;function EscapeComFunction(dwFunc:Dword):boolean;
begin
result:=FALSE;
if hCom<>INVALID_HANDLE_VALUE then
result := EscapeCommFunction(hCom,dwFunc);
end;
//////////////////////////////////////////////////////////
// FUNCTION: GetComModemStatus
//
// PURPOSE: Read the state of modem input pin right now
//
// PARAMETERS:
// none
//
// RETURN VALUE:
//
// A DWORD variable containing one or more of following codes:
//
// Value Meaning
// ---------- -----------------------------------------------------------
// MS_CTS_ON The CTS (clear-to-send) signal is on.
// MS_DSR_ON The DSR (data-set-ready) signal is on.
// MS_RING_ON The ring indicator signal is on.
// MS_RLSD_ON The RLSD (receive-line-signal-detect) signal is on.
//
// If this comm have bad handle or not yet opened, the return value is 0
//
// COMMENTS:
//
// This member function calls GetCommModemStatus and return its value.
// Before calling this member function, you must have a successful
// 'StartOpen' call.
//
//
function GetComModemStatus : DWORD;
var
dwModemState : DWORD;
begin
if hCom<>INVALID_HANDLE_VALUE then
if not GetCommModemStatus( hCom, dwModemState ) then
Result := 0
else
Result := dwModemState
end;end.
第二代是 汇编
第三代是 C
第四代是 Delphi胡诌,让什么老教授晕一下.