win2000串口求助。(我在csdn上无人可以回答)高分200!(200分)

  • 主题发起人 主题发起人 ytdxl
  • 开始时间 开始时间
Y

ytdxl

Unregistered / Unconfirmed
GUEST, unregistred user!
我用delphi3.0在win98下写了一段串口通讯的程序,可以正常使用,可是同样的,
在win2000下,却不能正常运行,请各位高手指正:
打开串口:
function TOperateCOM.InitCOM :BooLean;
var
HandleID :Dword;
SFileName:String; iUseWhatCOM:integer;
tTIniFile:TIniFile;
begin
sFileName:='c:/'+S21Dir+'/ZdSystem.ini';
tTIniFile:=TIniFile.Create(sFileName);
iUseWhatCOM:=tTIniFile.Readinteger('COM','COM',1 );
HandleID:=-1;
CASE iUseWhatCOM Of
1: HandleID :=createfile('COM1',generic_read or
generic_write,0,nil,open_existing,
file_attribute_normal or
file_flag_overlapped,0);
2: HandleID :=CreateFile('COM2', GENERIC_READ or GENERIC_WRITE,
0, Nil,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED,
0);
END;
tTIniFile.Free;
If HandleID =-1
Then begin
ShowCOMError;
result :=FALSE;
End
Else begin
SetCommMask( HandleID, EV_RXCHAR) ;
SetupComm(HandleID, 4096, 4096 ) ;
PurgeComm(HandleID, PURGE_TXABORT or PURGE_RXABORT or
PURGE_TXCLEAR or PURGE_RXCLEAR );

GetCommTimeouts(HandleId,COMMTIMEOUTS);
COMMTIMEOUTS.ReadIntervalTimeout:=10;
COMMTIMEOUTS.ReadTotalTimeoutMultiplier:=12;
COMMTIMEOUTS.ReadTotalTimeoutConstant:=10;
SetCommTimeouts(HandleId,COMMTIMEOUTS);

GetCommState(HandleID, dcb );
dcb.DCBlength :=sizeof( DCB );
Dcb.BaudRate :=CBR_4800;
Dcb.ByteSize :=8;
Dcb.Parity :=2;
Dcb.Stopbits :=0;
SetCommState(HandleID, dcb);
OperateCOM.COMHandle :=HandleID;
result :=TRUE;
ComBusy :=False;
End;
end;

写出数据:
function TOperateCOM.WriteBytesToCom( ByteNum :Dword; buf :array of byte) :BooLean;
var
dwBytesWritten, i :Dword ;
overlp :POverLapped; //OverLapped
Label EXCEPTIONEND;
begin
While ComBusy=True do;
ComBusy :=True;
Result:=TRUE;
dwBytesWritten:=0;
For i :=0 to ByteNum-1 do
Begin
Try
//result :=WriteFile(COMHandle, buf, 1, dwBytesWritten, lpol);

result :=WriteFile(COMHandle, buf, 1, dwBytesWritten, NIL);
Except
ShowCOMError;
End;
If Result=False
Then Begin
ShowCOMError;
Goto EXCEPTIONEND;
End;
End;
EXCEPTIONEND:
ComBusy :=False;
end;

总是
Result=False
我用
result :=WriteFile(COMHandle, buf, 1, dwBytesWritten, lpol);
lpol是我定义的全局变量 POverLapped;
也是Result=false;
用com1和com2两种打开方式,结果是一样的,但二者的句柄不一样。
有什么问题,请告诉指正。ytdxl@21cn.com 谢谢!


 
没人理我?[:(!]
 
我给你一段采用api写的发送数据!
unit sendmbunit;

interface

uses
Classes,windows,SysUtils;

type
comm_sendmb = class(TThread)
private
fname:string;
hwriteEvent:THandle;
hcomfile: THandle;
protected
procedure Execute; override;
public
constructor create(sendfilename:string);
function initcom: integer;//初始化
function sendbuffer(buffer: Pchar; count: integer): boolean;//发送字符
function sendfl: integer;//发送文件
function closecomfile: integer;
end;

implementation
uses wait;
constructor comm_sendmb.create(sendfilename:string);
begin
fname:=sendfilename;
inherited create(false);
end;
function comm_sendmb.closecomfile: integer;
begin
CloseHandle(hComFile);
CloseHandle(hwriteEvent);
result:=1;
end;
function comm_sendmb.sendfl: integer;
var
buf:array[1..512] of Char;
buffer:PChar;
FromF: file;
NumRead,i,len: Integer;
str:string;
label endlabel;
begin
result:=0;
if initcom >10 then
begin
result:=998;
exit;
end;
AssignFile(FromF,fname);
Reset(FromF, 1);
len:=FileSize(FromF);


str:=inttostr(len);
if length(str)<8 then
begin
while length(str)<8 do
begin
str:='0'+str;
end;
end;
str:=#3+#3+str;
buffer:=PChar(str);
sendbuffer(buffer,length(str));

len:=(len+511) div 512;
waitform.ProgressBar1.Min:=0;
waitform.ProgressBar1.Max:=len;
len:=0;
repeat
begin
fillchar(Buf,sizeof(Buf),#0);
BlockRead(FromF, buf, SizeOf(Buf), NumRead);
buffer:=PChar(@buf);
for i:=1 to 3 do
begin
if Terminated then
goto endlabel;
if sendbuffer(buffer,NumRead) then
break;
end;
if i>3 then
begin
result:=1;
//raise ERangeError.Create( '传输失败!' );
break;
end;
//len:=len+NumRead;
waitform.ProgressBar1.Position:=waitform.ProgressBar1.Position+1;
//memo1.Lines.Add('已经发送的字节:'+inttostr(len));
end;
until ((NumRead = 0) or (NumRead<SizeOf(Buf)));
endlabel:
CloseFile(FromF);
closecomfile;
end;

function comm_sendmb.initcom: integer;
var
commtimeouts: TCommTimeouts;
dcb: Tdcb;
commprop: TCommProp;
fdwEvtMask: DWORD;

begin
hwriteEvent:= CreateEvent( nil, True, False, nil );
hcomfile:=CreateFile( PChar('com1'),GENERIC_READ or GENERIC_WRITE,
0,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);

//if hcomfile = INVALID_HANDLE_VALUE then
// raise ERangeError.Create( 'Error opening serial port' );
if hcomfile = INVALID_HANDLE_VALUE then
begin
result:=998;
exit;
end;

if GetFileType( hcomfile ) <> FILE_TYPE_CHAR then
begin
CloseHandle( hcomfile );
raise ERangeError.Create( 'File handle is not a comm handle ' );
end;
GetCommState( hcomfile, dcb );
SetCommMask( hcomfile, EV_RXCHAR);
SetupComm( hcomfile, 4096, 4096 );

PurgeComm( hcomfile, PURGE_TXABORT or PURGE_RXABORT or PURGE_TXCLEAR or PURGE_RXCLEAR ) ;
//填写超时
commtimeouts.ReadIntervalTimeout :=0;
commtimeouts.ReadTotalTimeoutMultiplier :=0;
commtimeouts.ReadTotalTimeoutConstant :=0;
commtimeouts.WriteTotalTimeoutMultiplier :=100;
commtimeouts.WriteTotalTimeoutConstant :=0;
SetCommTimeouts( hcomfile, commtimeouts );

{dcb.fAbortOnError := False; NOT VALID}
dcb.DCBlength:=sizeof( DCB );
//dcb.BaudRate := CBR_115200;
dcb.BaudRate := CBR_57600;
dcb.Flags := dcb.Flags or 1; // Enable fBinary
dcb.Flags := dcb.Flags or 2; // 进行校验

//DCB.wReserved1:=65;
//DCB.wReserved:=0;

//dcb.Flags := dcb.Flags or $10;
//dcb.Flags := dcb.Flags or $1000;
{dcb.XonLim :=10;
dcb.XoffLim :=10;
dcb.XonChar :=#0;
dcb.XoffChar :=#0;}
dcb.ByteSize :=8;
dcb.Parity := EVENPARITY;
dcb.StopBits :=ONESTOPBIT;
SetCommState( hcomfile, dcb );
EscapeCommFunction(hcomfile, SETDTR );
//closehandle(hcomfile);
//hcomfile:=CreateFile( PChar('com1'),GENERIC_READ or GENERIC_WRITE,
//0,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
sleep(100);
result:=0;
end;
function comm_sendmb.sendbuffer(buffer: Pchar; count: integer): boolean;
var
sendbuf:Pchar;
sendbool:boolean;
truewr,dwLastError,dwErrors:DWORD;
i:integer;
dwModemStat,dwritek,StartWriting:DWORD;
ctsbool:boolean;
modd:integer;
sendcount:integer;
begin
result:=false;
sendbuf:=buffer;
sendcount:=count;
dwModemStat:=0;
GetCommModemStatus(hcomfile,dwModemStat);
if(MS_CTS_ON= dwModemStat and MS_CTS_ON) then
ctsbool:=true
else
ctsbool:=false;
i:=0;
while (not(ctsbool) and (i<30)) do
begin
if Terminated then
exit;
sleep(100);
GetCommModemStatus(hcomfile,dwModemStat);
if(MS_CTS_ON= dwModemStat and MS_CTS_ON) then
ctsbool:=true;
i:=i+1;
end;
if i>=30 then
begin
exit;
end;

dwritek:=0;
StartWriting:=0;
i:=0;
sendbool:=WriteFile( hComFile,sendbuf^,sendcount,dwritek,nil);
sleep(50);
if not(sendbool) then
begin
dwLastError := GetLastError;
if dwLastError <> ERROR_IO_PENDING then
begin
while (WaitForSingleObject(hwriteEvent,500)=WAIT_TIMEOUT) do
begin
dwLastError := GetLastError;
if(dwLastError <> ERROR_IO_INCOMPLETE) then
begin
ClearCommError(hComFile,dwErrors, nil);
break;
end;
end;
end
else
begin
ClearCommError(hComFile,dwErrors, nil);
end;
end
else
result:=true;
end;

procedure comm_sendmb.Execute;
begin
if fileexists(fname) then
if sendfl>10 then
begin
waitform.Label1.Caption:=' 端口已经被占用!';
waitform.ProgressBar1.hide;
waitform.Label1.visible:=true;
exit;
end;
waitform.close;
end;

end.
 
谢谢,可是我看和我的代码没 什么区别呀?
不一样的地方,PChar('com1')等,我也换了,也不对,你的代码,
你在win2000下用过你的代码吗?
 
你可以用TurboPower Software Company 的Async Professional 控件可以用,
我用了没有问题的,在WIN2000下。
 
我有比大家提到到的更好的东西,是Pcomm.dll,在win98,win2000下都很好用。
我现在是比较疑惑,我想知道在win2000下不行的原因。(大家如果对Pcomm.dll有兴趣,
我可以共享给大家,是台湾摩砂的,做串口的老大)。我感觉可能是某些东西被禁用了,
想与大家探讨这方面的问题
 
后退
顶部