首页  编辑  

串口初始化

Tags: /超级猛料/Network.网络通讯/Comm.串口通讯/   Date Created:

串口初始化

串口创建之后,必须初始化,初始化包括:波特率,DCB,Timeout,Mask。

其中Mask是非常重要的一环,必须设定,否则在Windows中,很可能异步操作模式收不到事件回调。

例如EV_RXCHAR设定之后,一旦串口收到EV_RXCHAR,就会在重叠I/O上触发一个事件,这样就可以在Event中产生一个wrSignaled信号,提醒程序读取数据了。

procedure InitCom(sCom: PChar; hCom: THandle);

var

 dcb: TDCB;

 ComStat: TComStat;

 Errors: DWORD;

 ctr: _COMMTIMEOUTS;

begin

 if hCom = INVALID_HANDLE_VALUE then Exit;

 PurgeComm(hCom, PURGE_TXCLEAR or PURGE_RXCLEAR or PURGE_RXABORT or PURGE_TXABORT);

 if not SetupComm(hCom, 1, 1) then

 begin

   FillChar(ComStat, SizeOf(ComStat), 0);

   ClearCommError(hCom, Errors, @ComStat);

 end;

 

 GetCommState(hCom, dcb);

 with dcb do

 begin

   BaudRate := CBR_115200;

   Parity := NOPARITY;

   StopBits := ONESTOPBIT;

   ByteSize := 8;

   XonChar :=  #17;

   XoffChar := #19;

   ErrorChar := #0;

   EofChar := #0;

   EvtChar := #0;

   XonLim := 10;

   XoffLim := 10;

   Flags := 1 or DTR_CONTROL_ENABLE or $80 or RTS_CONTROL_ENABLE or $00004000;

 end;

 SetCommState(hCom, dcb);

 FillChar(ctr, SizeOf(ctr), 0);

 ctr.ReadIntervalTimeout := MAXDWORD;

 SetCommTimeouts(hCom, ctr);

 SetCommMask(hCom, EV_RXCHAR or EV_RXFLAG or EV_TXEMPTY or EV_CTS or EV_DSR or EV_RLSD or EV_ERR or EV_RING);

end;

// 读取窗口,异步模式,超时等待,只要在Timeeout时间内有数据读取即返回

function ReadCom(hCom: THandle; const Timeout: Integer = 200): string;

var

 FRet: array[0..1023] of char;

 R : DWORD;

 ol: TOverlapped;

 E : TEvent;

 idx : DWORD;

 wr: TWaitResult;

begin

 Result := '';

 FillChar(FRet, SizeOf(FRet), 0);

 E := TEvent.Create(nil, True, False, '');

 ol.hEvent := E.Handle;

 R := 0;

 idx := 0;

 

 if not ReadFile(hCom, FRet[0], SizeOf(FRet), idx, @ol) then

 begin

   if GetLastError = ERROR_IO_PENDING then

   begin

     wr := E.WaitFor(Timeout);

     case wr of

       wrSignaled:

         repeat   // 不断循环读取直到读取完成为止

           // 必须设定bWait为False,否则会阻塞

           GetOverlappedResult(hCom, ol, R, False);

           Inc(idx, R);

           if R = 0 then Break;

           ReadFile(hCom, FRet[idx], SizeOf(FRet), R, @ol);

           Sleep(500);

         until False;

       wrTimeout, wrAbandoned, wrError:

         begin

           // 必须设定bWait为False,否则会阻塞

           GetOverlappedResult(hCom, ol, R, False);

           Inc(idx, R);

           ReadFile(hCom, FRet[idx], SizeOf(FRet), R, @ol);

         end

     else

       //

     end;

   end;

 end;

 SetString(Result, FRet, idx);

end;

// 写串口,重叠IO,异步IO模式

function WriteCom(hCom: THandle; Data: string; const Timeout: Integer = 100): Boolean;

var

 R: DWORD;

 ol: TOverlapped;

 E : TEvent;

 wr: TWaitResult;

begin

 FillChar(ol, SizeOf(ol), 0);

 E := TEvent.Create(nil, True, False, '');

 ol.hEvent := E.Handle;

 PurgeComm(hCom, PURGE_TXCLEAR or PURGE_RXCLEAR or PURGE_RXABORT or PURGE_TXABORT);

 if not WriteFile(hCom, PChar(Data)^, Length(Data), R, @ol) then

 begin

   if GetLastError = ERROR_IO_PENDING then

   begin

     wr := E.WaitFor(Timeout);

     case wr of

       wrSignaled: GetOverlappedResult(hCom, ol, R, True);

       wrTimeout: ;

       wrAbandoned: ;

       wrError: ;

     end;

   end;

 end;

 Result := DWORD(Length(Data)) = R;

end;