用SPComm单元中的TCOmm类通过串口发送数据,点一下发送一条时接收方可以正确接收,如果点的速度过快则接收方出错.用了一个定时器1秒发一条也是正常的,但不能更快了.请问这是什么原因,如何避免这个错误.
解决方案 »
- 关于线程引发Access violation at address的问题
- 一组ADODataset+Datasource大概占用多少内存?
- 想更新整个表,为什么只更新了第一条??
- fastreport分组问题
- 做了个小游戏,是关于24点的益智游戏,大家评评看!up有分!
- 还是有关DBF的问题
- 多线程+MDI+DB,开发中遇到的问题,请执教!
- 网上下载的控件如何使用?在线等待
- 急急急急!!!!!! Dephi如何进行文件操作
- 我怎样实现在显示主窗体前显示并控制其它窗体?
- fastreport 做主從報表時為什麼當從報表沒有記錄時報表不會顯示這條記錄,該怎麼解決?
- 奇怪的串口发送问题,如果其中一个号码为一万零一时就接收错误
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胡诌,让什么老教授晕一下.