小弟最近编的程序,出现了很怪的问题,在有的电脑上数据能正常接收,在有的电脑上(性能相对差一些)接收到的数字却是乱的,连字节数都不对,想了几天至今仍一筹莫展。求高手指教!代码大致如下:
//...串口初始化设置
PostEvent:=CreateEvent(nil,True,True,nil);
if PostEvent=null then
begin
MessageBox(0,'Create Event Error','Notice',MB_OK);
Form1.StatusBar1.panels[0].Text := '串口打开失败';
Exit;
end;
ReadOs.hEvent :=CreateEvent(nil,true,False,nil);
if ReadOs.hEvent=null then
begin
MessageBox(0,'Create Event Error','Notice',MB_OK);
CloseHandle(PostEvent);
StatusBar1.panels[0].Text := '串口打开失败';
Exit;
end;
CommHandle:= CreateFile(pchar('COM'+H),GENERIC_WRITE or GENERIC_READ,
0,nil,OPEN_EXISTING,FILE_FLAG_OVERLAPPED or FILE_ATTRIBUTE_NORMAL,0);
if CommHandle = INVALID_HANDLE_VALUE then
begin
CloseHandle(PostEvent);
CloseHandle(ReadOs.hEvent);
MessageBox(0,'串口打开失败','Notice',MB_OK);
StatusBar1.panels[0].Text := '串口打开失败';
Exit;
end;
form1.StatusBar1.panels[0].Text:= '已与端口COM'+H+' 连接!';
CommTimeOut.ReadIntervalTimeout := MAXDWORD;
CommTimeOut.ReadTotalTimeoutMultiplier := 0;
CommTimeOut.ReadTotalTimeoutConstant := 0;
Commtimeout.WriteTotalTimeoutMultiplier:=0;
Commtimeout.WriteTotalTimeoutConstant:=0;
SetCommTimeouts(CommHandle, CommTimeOut);
SetupComm(CommHandle,4096,1024);
GetCommState(CommHandle,DCB);
DCB.BaudRate:=9600;
DCB.ByteSize:=8;
DCB.Parity:=NOPARITY;
DCB.StopBits:=ONESTOPBIT;
Connected:=SetCommState(CommHandle,DCB);
if (not SetCommMask(CommHandle,EV_RXCHAR)) then
begin
MessageBox(0,'Set CommMask Error','Notice',MB_OK);
Exit;
end;
ReadData;
end;procedure TForm1.ReadData;
var
com_thread:Thandle;
ThreadID:DWORD;
begin
if not Connected then
begin
Form1.StatusBar1.panels[0].Text:='未打开串口';
Exit;
end;
FillChar(ReadOs,sizeof(readOs),0);
ReadOs.Offset:=0;
ReadOs.OffsetHigh:=0;
Com_Thread:=CreateThread(nil,0,@CommWatch,nil,0,ThreadID);
if (Com_thread=0) then
Application.messagebox('No Create Thread!',nil,mb_OK);
end;procedure CommWatch(Ptr:Pointer);stdcall;
var
dwEvtMask,dwTranser:Dword;
PostMsgFlag:Boolean;
overlapped:Toverlapped;
begin
Receive:=True;
FillChar(overlapped,SizeOf(overlapped),0);
overlapped.hEvent:=CreateEvent(nil,True,False,nil);
if overlapped.hEvent=null then
begin
MessageBox(0,'overlapped.Event Create Error','Notice',MB_OK);
Exit;
end;
while(Receive) do
begin
dwEvtMask:=0;
if not WaitCommEvent(CommHandle,dwEvtMask,@overlapped) then
begin
if ERROR_IO_PENDING=GetLastError then
GetOverLappedResult(CommHandle,overlapped,dwTranser,True);
end;
if ((dwEvtMask and EV_RXCHAR)=EV_RXCHAR) then
begin
WaitForSingleObject(Postevent,INFINITE);
ResetEvent(PostEvent);
PostMsgFlag:=PostMessage(Form1.Handle,WM_COMMNOTIFY,CommHandle,0);
if (not PostMsgFlag) then
begin
MessageBox(0,'PostMessage Error','Notice',MB_OK);
Exit;
end;
end;
end;
CloseHandle(overlapped.hEvent);
end;procedure TForm1.WMCOMMNOTIFY(var Message:TMessage);
var
CommState:ComStat;
dwNumberOfBytesRead:Dword;
ErrorFlag:Dword;
InputBuffer:Array[0..255] of Byte;
begin
Sleep(50);
if not ClearCommError(CommHandle,ErrorFlag,@CommState) then
begin
MessageBox(0,'ClearCommError','Notice',MB_OK);
PurgeComm(CommHandle,Purge_Rxabort or Purge_Rxclear);
Exit;
end;
if CommState.cbInQue>0 then
begin
Fillchar(InputBuffer,256,0);
if (not ReadFile(CommHandle,InputBuffer,CommState.cbInQue,dwNumberOfBytesRead,@ReadOs)) then
begin
ErrorFlag:=GetLastError();
if (ErrorFlag <> 0) and (ErrorFlag <> ERROR_IO_PENDING) then
begin
MessageBox(0,'ReadFile Error','Notice',MB_OK);
Receive :=False;
CloseHandle(ReadOs.hEvent);
CloseHandle(PostEvent);
CloseHandle(CommHandle);
Exit;
end
else
begin
WaitForSingleObject(CommHandle,INFINITE);
GetOverlappedResult(CommHandle,ReadOs,dwNumberOfBytesRead,False);
end;
end;
if dwNumberOfBytesRead>0 then
begin
Statusbar1.Panels[1].Text:=format('已接收%d字节',CommState.cbInQue]);
//..提取接收数据后用于处理显示部分代码
end;
end;
SetEvent(PostEvent);
end;
//...串口初始化设置
PostEvent:=CreateEvent(nil,True,True,nil);
if PostEvent=null then
begin
MessageBox(0,'Create Event Error','Notice',MB_OK);
Form1.StatusBar1.panels[0].Text := '串口打开失败';
Exit;
end;
ReadOs.hEvent :=CreateEvent(nil,true,False,nil);
if ReadOs.hEvent=null then
begin
MessageBox(0,'Create Event Error','Notice',MB_OK);
CloseHandle(PostEvent);
StatusBar1.panels[0].Text := '串口打开失败';
Exit;
end;
CommHandle:= CreateFile(pchar('COM'+H),GENERIC_WRITE or GENERIC_READ,
0,nil,OPEN_EXISTING,FILE_FLAG_OVERLAPPED or FILE_ATTRIBUTE_NORMAL,0);
if CommHandle = INVALID_HANDLE_VALUE then
begin
CloseHandle(PostEvent);
CloseHandle(ReadOs.hEvent);
MessageBox(0,'串口打开失败','Notice',MB_OK);
StatusBar1.panels[0].Text := '串口打开失败';
Exit;
end;
form1.StatusBar1.panels[0].Text:= '已与端口COM'+H+' 连接!';
CommTimeOut.ReadIntervalTimeout := MAXDWORD;
CommTimeOut.ReadTotalTimeoutMultiplier := 0;
CommTimeOut.ReadTotalTimeoutConstant := 0;
Commtimeout.WriteTotalTimeoutMultiplier:=0;
Commtimeout.WriteTotalTimeoutConstant:=0;
SetCommTimeouts(CommHandle, CommTimeOut);
SetupComm(CommHandle,4096,1024);
GetCommState(CommHandle,DCB);
DCB.BaudRate:=9600;
DCB.ByteSize:=8;
DCB.Parity:=NOPARITY;
DCB.StopBits:=ONESTOPBIT;
Connected:=SetCommState(CommHandle,DCB);
if (not SetCommMask(CommHandle,EV_RXCHAR)) then
begin
MessageBox(0,'Set CommMask Error','Notice',MB_OK);
Exit;
end;
ReadData;
end;procedure TForm1.ReadData;
var
com_thread:Thandle;
ThreadID:DWORD;
begin
if not Connected then
begin
Form1.StatusBar1.panels[0].Text:='未打开串口';
Exit;
end;
FillChar(ReadOs,sizeof(readOs),0);
ReadOs.Offset:=0;
ReadOs.OffsetHigh:=0;
Com_Thread:=CreateThread(nil,0,@CommWatch,nil,0,ThreadID);
if (Com_thread=0) then
Application.messagebox('No Create Thread!',nil,mb_OK);
end;procedure CommWatch(Ptr:Pointer);stdcall;
var
dwEvtMask,dwTranser:Dword;
PostMsgFlag:Boolean;
overlapped:Toverlapped;
begin
Receive:=True;
FillChar(overlapped,SizeOf(overlapped),0);
overlapped.hEvent:=CreateEvent(nil,True,False,nil);
if overlapped.hEvent=null then
begin
MessageBox(0,'overlapped.Event Create Error','Notice',MB_OK);
Exit;
end;
while(Receive) do
begin
dwEvtMask:=0;
if not WaitCommEvent(CommHandle,dwEvtMask,@overlapped) then
begin
if ERROR_IO_PENDING=GetLastError then
GetOverLappedResult(CommHandle,overlapped,dwTranser,True);
end;
if ((dwEvtMask and EV_RXCHAR)=EV_RXCHAR) then
begin
WaitForSingleObject(Postevent,INFINITE);
ResetEvent(PostEvent);
PostMsgFlag:=PostMessage(Form1.Handle,WM_COMMNOTIFY,CommHandle,0);
if (not PostMsgFlag) then
begin
MessageBox(0,'PostMessage Error','Notice',MB_OK);
Exit;
end;
end;
end;
CloseHandle(overlapped.hEvent);
end;procedure TForm1.WMCOMMNOTIFY(var Message:TMessage);
var
CommState:ComStat;
dwNumberOfBytesRead:Dword;
ErrorFlag:Dword;
InputBuffer:Array[0..255] of Byte;
begin
Sleep(50);
if not ClearCommError(CommHandle,ErrorFlag,@CommState) then
begin
MessageBox(0,'ClearCommError','Notice',MB_OK);
PurgeComm(CommHandle,Purge_Rxabort or Purge_Rxclear);
Exit;
end;
if CommState.cbInQue>0 then
begin
Fillchar(InputBuffer,256,0);
if (not ReadFile(CommHandle,InputBuffer,CommState.cbInQue,dwNumberOfBytesRead,@ReadOs)) then
begin
ErrorFlag:=GetLastError();
if (ErrorFlag <> 0) and (ErrorFlag <> ERROR_IO_PENDING) then
begin
MessageBox(0,'ReadFile Error','Notice',MB_OK);
Receive :=False;
CloseHandle(ReadOs.hEvent);
CloseHandle(PostEvent);
CloseHandle(CommHandle);
Exit;
end
else
begin
WaitForSingleObject(CommHandle,INFINITE);
GetOverlappedResult(CommHandle,ReadOs,dwNumberOfBytesRead,False);
end;
end;
if dwNumberOfBytesRead>0 then
begin
Statusbar1.Panels[1].Text:=format('已接收%d字节',CommState.cbInQue]);
//..提取接收数据后用于处理显示部分代码
end;
end;
SetEvent(PostEvent);
end;
解决方案 »
- ADO中CursorLocation = UseServer时,如何避免记录丢失?
- 大家好,关于数据库出现了这样的问题 修改不了表中的字段 急!
- vclskin 皮肤应用-- 窗体停靠到panel上,窗体中的控件失效,高手来啊!
- TWindowsMediaPlayer必须要安装media player 9.0吗???
- 请帮助解决TFileStream的问题?有代码!紧急!!!
- 菜鸟问题---如何将声音文件做到EXE文件里?
- 解决Shift,Ctrl,Alt按键的“锁住”与“释放”的问题,有意者请入。
- 连接ACCESS数据库的问题?
- 谁能给我TWinThread控件或下载地方?
- 请问ADO2.7是ADO.NET吗?比2.6有什么不同?在Delphi中使用有没有什么问题?
- ini文件数据读取问题!
- delphi中帮助文件是如何创建的呀,请教
http://community.csdn.net/Expert/topic/5390/5390715.xml?temp=.3695642
http://community.csdn.net/Expert/topic/5462/5462642.xml?temp=.6457483