16,746
社区成员




function TComm232.InitComm(Str_CommName,Str_BaudRate,Str_DataSize,Str_StopBits,Str_Parity:string):Integer;
var
i_BaudRate,i_ByteSizeIndex,i_StopBitsIndex,i_ParityIndex:Integer;
begin
Result:=0;
i_BaudRate:=StrToIntDef(Str_BaudRate,230400);
if Str_DataSize='5' then i_ByteSizeIndex:=0
else if Str_DataSize='6' then i_ByteSizeIndex:=1
else if Str_DataSize='7' then i_ByteSizeIndex:=2
else if Str_DataSize='8' then i_ByteSizeIndex:=3
else i_ByteSizeIndex:=3;
if Str_StopBits='2' then i_StopBitsIndex:=2
else if Str_StopBits='1.5' then i_StopBitsIndex:=1
else if Str_StopBits='1' then i_StopBitsIndex:=0;
if Str_Parity='Even' then i_ParityIndex:=0
else if Str_Parity='Mark' then i_ParityIndex:=1
else if Str_Parity='None' then i_ParityIndex:=2
else if Str_Parity='Odd' then i_ParityIndex:=3
else if Str_Parity='Space' then i_ParityIndex:=4
else i_ParityIndex:=2;
Comm.CommName:='//./'+Str_CommName;
Comm.BaudRate:=i_Baudrate;
Comm.ByteSize:=TEumn_ByteSize[i_ByteSizeIndex];
Comm.StopBits:=TEumn_StopBits[i_StopBitsIndex];
Comm.Parity:=TEumn_Parity[i_ParityIndex];
Comm.Outx_CtsFlow:= False;
Comm.Outx_DsrFlow:=False;
Comm.DtrControl:=DtrDisable;
Comm.TxContinueOnXoff:=False;
Comm.RtsControl:=RtsDisable;
Comm.XonLimit:=4096;
Comm.XoffLimit:=1024;
Comm.ReadIntervalTimeout:=1;
//Start
Comm.Inx_XonXoffFlow:=False;
Comm.Outx_XonXoffFlow:=False;
Comm.StopComm;
try
Comm.StartComm;
Sleep(180);
except
Result:=-1;
Comm.StopComm;
Exit;
end;
end;
Comm.Outx_CtsFlow:= False;
Comm.Outx_DsrFlow:=False;
Comm.DtrControl:=DtrDisable;
Comm.TxContinueOnXoff:=False;
Comm.RtsControl:=RtsDisable;
这个不要,也不要去修改那些掩码,不要修改SPCOMM,原来是我发送字符的时候要这样的格式: Send_Str+#13+#10,增加了#13#10,我是通过虚拟串口助手,使用QCom发送到串口助手上,自己的软件也发送到串口助手上,对比发现发送字符串要回车换行~
procedure TComm.StartComm;
var
hNewCommFile: THandle;
begin
// Are we already doing comm?
if (hCommFile <> 0) then
raise ECommsError.Create( 'This serial port already opened' );
hNewCommFile := CreateFile( PChar(FCommName),
GENERIC_READ or GENERIC_WRITE,
0, {not shared}
nil, {no security ??}
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED,
0 {template} );
if hNewCommFile = INVALID_HANDLE_VALUE then
raise ECommsError.Create( 'Error opening serial port' );
// Is this a valid comm handle?
if GetFileType( hNewCommFile ) <> FILE_TYPE_CHAR then
begin
CloseHandle( hNewCommFile );
raise ECommsError.Create( 'File handle is not a comm handle ' )
end;
if not SetupComm( hNewCommFile, 4096, 4096 ) then
begin
CloseHandle( hCommFile );
raise ECommsError.Create( 'Cannot setup comm buffer' )
end;
// It is ok to continue.
hCommFile := hNewCommFile;
// purge any information in the buffer
PurgeComm( hCommFile, PURGE_TXABORT or PURGE_RXABORT or
PURGE_TXCLEAR or PURGE_RXCLEAR ) ;
SetCommMask(hCommFile,EV_RXCHAR or EV_TXEMPTY or EV_CTS or //Add 20140826
EV_DSR or EV_RLSD or EV_BREAK or
EV_ERR or EV_RING);
PurgeComm( hCommFile, PURGE_TXABORT or PURGE_RXABORT or //Add 20140826
PURGE_TXCLEAR or PURGE_RXCLEAR ) ;
FSendDataEmpty := True;
// Setting the time-out value
_SetCommTimeout;
// Querying then setting the comm port configurations.
_SetCommState;
// Create the event that will signal the threads to close.
hCloseEvent := CreateEvent( nil, True, False, nil );
if hCloseEvent = 0 then
begin
CloseHandle( hCommFile );
hCommFile := 0;
raise ECommsError.Create( 'Unable to create event' )
end;
// Create the Read thread.
try
ReadThread := TReadThread.Create( True {suspended} );
except
ReadThread := nil;
CloseHandle( hCloseEvent );
CloseHandle( hCommFile );
hCommFile := 0;
raise ECommsError.Create( 'Unable to create read thread' )
end;
ReadThread.hCommFile := hCommFile;
ReadThread.hCloseEvent := hCloseEvent;
ReadThread.hComm32Window := FHWnd;
// Comm threads should have a higher base priority than the UI thread.
// If they don't, then any temporary priority boost the UI thread gains
// could cause the COMM threads to loose data.
ReadThread.Priority := tpHighest;
// Create the Write thread.
try
WriteThread := TWriteThread.Create( True {suspended} );
except
CloseReadThread;
WriteThread := nil;
CloseHandle( hCloseEvent );
CloseHandle( hCommFile );
hCommFile := 0;
raise ECommsError.Create( 'Unable to create write thread' )
end;
WriteThread.hCommFile := hCommFile;
WriteThread.hCloseEvent := hCloseEvent;
WriteThread.hComm32Window := FHWnd;
WriteThread.pFSendDataEmpty := @FSendDataEmpty;
WriteThread.Priority := tpHigher;
ReadThread.Resume;
WriteThread.Resume
// Everything was created ok. Ready to go!
end; {TComm.StartComm}
procedure TReadThread.Execute;
var
szInputBuffer: array[0..INPUTBUFFERSIZE-1] of Char;
nNumberOfBytesRead: DWORD;
HandlesToWaitFor: array[0..2] of THandle;
dwHandleSignaled: DWORD;
fdwEvtMask: DWORD;
// Needed for overlapped I/O (ReadFile)
overlappedRead: TOverlapped;
// Needed for overlapped Comm Event handling.
overlappedCommEvent: TOverlapped;
label
EndReadThread;
begin
FillChar( overlappedRead, Sizeof(overlappedRead), 0 );
FillChar( overlappedCommEvent, Sizeof(overlappedCommEvent), 0 );
// Lets put an event in the Read overlapped structure.
overlappedRead.hEvent := CreateEvent( nil, True, True, nil);
if overlappedRead.hEvent = 0 then
begin
PostHangupCall;
goto EndReadThread
end;
// And an event for the CommEvent overlapped structure.
overlappedCommEvent.hEvent := CreateEvent( nil, True, True, nil);
if overlappedCommEvent.hEvent = 0 then
begin
PostHangupCall();
goto EndReadThread
end;
// We will be waiting on these objects.
HandlesToWaitFor[0] := hCloseEvent;
HandlesToWaitFor[1] := overlappedCommEvent.hEvent;
HandlesToWaitFor[2] := overlappedRead.hEvent;
// Setup CommEvent handling.
// Set the comm mask so we receive error signals.
// if not SetCommMask(hCommFile, EV_ERR or EV_RLSD or EV_RING ) then
// begin
// PostHangupCall;
// goto EndReadThread
// end;
if not SetCommMask(hCommFile,EV_RXCHAR or EV_TXEMPTY or EV_CTS or //Modification 20140826
EV_DSR or EV_RLSD or EV_BREAK or
EV_ERR or EV_RING) then
begin
PostHangupCall;
goto EndReadThread
end;
// Start waiting for CommEvents (Errors)
if not SetupCommEvent( @overlappedCommEvent, fdwEvtMask ) then
goto EndReadThread;
// Start waiting for Read events.
if not SetupReadEvent( @overlappedRead,
szInputBuffer, INPUTBUFFERSIZE,
nNumberOfBytesRead ) then
goto EndReadThread;
// Keep looping until we break out.
while True do
begin
// Wait until some event occurs (data to read; error; stopping).
dwHandleSignaled := WaitForMultipleObjects(3, @HandlesToWaitFor,
False, INFINITE);
// Which event occured?
case dwHandleSignaled of
WAIT_OBJECT_0: // Signal to end the thread.
begin
// Time to exit.
goto EndReadThread
end;
WAIT_OBJECT_0 + 1: // CommEvent signaled.
begin
// Handle the CommEvent.
if not HandleCommEvent( @overlappedCommEvent, fdwEvtMask, TRUE ) then
goto EndReadThread;
// Start waiting for the next CommEvent.
if not SetupCommEvent( @overlappedCommEvent, fdwEvtMask ) then
goto EndReadThread
{break;??}
end;
WAIT_OBJECT_0 + 2: // Read Event signaled.
begin
// Get the new data!
if not HandleReadEvent( @overlappedRead,
szInputBuffer,
INPUTBUFFERSIZE,
nNumberOfBytesRead ) then
goto EndReadThread;
// Wait for more new data.
if not SetupReadEvent( @overlappedRead,
szInputBuffer, INPUTBUFFERSIZE,
nNumberOfBytesRead ) then
goto EndReadThread
{break;}
end;
WAIT_FAILED: // Wait failed. Shouldn't happen.
begin
PostHangupCall;
goto EndReadThread
end
else // This case should never occur.
begin
PostHangupCall;
goto EndReadThread
end
end {case dwHandleSignaled}
end; {while True}
// Time to clean up Read Thread.
EndReadThread:
PurgeComm( hCommFile, PURGE_RXABORT + PURGE_RXCLEAR );
CloseHandle( overlappedRead.hEvent );
CloseHandle( overlappedCommEvent.hEvent )
end; {TReadThread.Execute}
//Start
Comm.Inx_XonXoffFlow:=False;
Comm.Outx_XonXoffFlow:=False;
Comm.StopComm;
try
Comm.StartComm;
m_CommMask:=EV_RXCHAR or EV_TXEMPTY or EV_CTS or EV_DSR or EV_RLSD or EV_BREAK or EV_ERR or EV_RING;
SetCommMask(Comm.Handle,m_CommMask);
Sleep(180);
except
Result:=-1;
Comm.StopComm;
Exit;
end;
constructor TComm232.Create();
begin
Inherited Create();
Comm:=TComm.Create(nil);
Comm.OnReceiveData:=CommReceiveData;
Gl_b_ReceivedEnd:=False;
end;
destructor TComm232.Destroy();
begin
try
Comm.OnReceiveData:=nil;
Comm.StopComm;
FreeAndNil(Comm);
except
end;
Application.ProcessMessages;
Inherited Destroy;
end;