2011-11-01 56 views
3

我在Delphi中創建一個簡單的程序,使用2個參數通過COM端口發送字符,第一個參數是端口號,第二個參數是要發送的字符。所以如果我將它保存爲p.exe,「p.exe 20 A」將通過COM20發送「A」。串口不會在delphi中工作

try 
    PhoneNumber := ParamStr(2); 

    if(StrToInt(ParamStr(1))>=10)then 
    CommPort := '\\.\COM'+ParamStr(1) 
    else 
    CommPort := 'COM'+ParamStr(1); 
    hCommFile := CreateFile(PChar(CommPort), 
          GENERIC_WRITE, 
          0, 
          nil, 
          OPEN_EXISTING, 
          FILE_ATTRIBUTE_NORMAL, 
          0); 
    if hCommFile=INVALID_HANDLE_VALUE then begin 
     ShowMessage('Unable to open '+ CommPort); 
    end; 
    if WriteFile(hCommFile, PChar(PhoneNumber)^, Length(PhoneNumber),NumberWritten, nil)=false then 
    showmessage('Unable to send'); 
    PurgeComm(hCommFile,PURGE_TXCLEAR); 
    FlushFileBuffers(hCommFile); 
    CloseHandle(hCommFile); 
    Application.Terminate; 
except 
    PurgeComm(hCommFile,PURGE_TXCLEAR); 
    FlushFileBuffers(hCommFile); 
    Application.Terminate; 
end; 

而且我還使用超級終端與COM編號baudrate = 9600,flow_control = none並且它給出了相同的結果。這個角色發送得很好。 問題是,我無法運行我的程序(p.exe),然後每次登錄到我的Windows XP時執行以下步驟: 通過超級終端連接到指定COM, 斷開連接。 然後我的可執行文件就可以運行了。否則,就像你在同一個COM中運行兩個超級終端會話一樣,它不起作用。有人得到一個提示回合呢?我錯過了我的代碼中的任何內容嗎?

+0

+1做超級終端進行仔細的檢查。 –

+0

因此,通過「不工作」,你會得到你的「無法打開......」錯誤,「無法發送」,或者是什麼? –

+0

您需要使用setcommstate來獲得波特率。 –

回答

4

我在代碼中看不到任何設置內容。所以也許你要依靠運行超級終端的副作用來爲你「灌輸」端口。看看這篇文章,他們通過這些東西去:波特率,奇偶校驗等。

http://www.delphi-central.com/serial.aspx

這似乎是一個完整的工作示例。看看你是否能夠得到這個工作,並將其作爲基礎來建立。

3

您需要使用setcommstate設置波特率和流量控制。

Function OpenPort(Var fHandle: THandle; fPort: String): Boolean; 
Const 
RxBufferSize  = 32; 
TxBufferSize  = 32; 
Var 
dcb    : TDCB; 
tms    : TCOMMTIMEOUTS; 
Begin 
Result := False; 
Try 
    If fHandle <> INVALID_HANDLE_VALUE Then 
    CloseHandle(fhandle); 
Except 
End; 
Try 
    //fport must be \\.\ URN format 
    fhandle := CreateFile(PChar(fPort), GENERIC_WRITE or GENERIC_READ, FILE_SHARE_WRITE , 
         Nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); 
    If (fhandle = INVALID_HANDLE_VALUE) Then 
    Begin 
    result := false; 
    exit; 
    End; 
    SetupComm(fhandle, RxBufferSize, TxBufferSize); 

    If pos('LPT', fPort) > 0 Then 
    // 
    Else 
    Begin 
    GetCommState(fhandle, dcb); 
    dcb.DCBlength := sizeof(dcb); 
    dcb.BaudRate := cbr_9600; 
    dcb.Flags := 1;      // binary... 
    if dtr_rts then 
    begin 
    dcb.flags := dcb.Flags Or $20;  //DTR HANDSHAKE 
    dcb.Flags := dcb.Flags Or $1000; //rts handshake 
    dcb.Flags := dcb.Flags Or 4;  //Outx_CtsFlow 
    dcb.Flags := dcb.Flags Or 8;  //Outx_DsrFlow 
    dcb.Flags := dcb.Flags Or $40;  //DsrSensitivity 
    //dcb.Flags := dcb.Flags or $100;//Outx_XonXoffFlow 
    //dcb.Flags := dcb.Flags or $200;//Inx_XonXoffFlow 
    end; 
    dcb.ByteSize := 8; 
    dcb.Parity := EVENPARITY; 
    dcb.StopBits := ONESTOPBIT; 
    SetCommState(fhandle, dcb); 
    GetCommTimeouts(fhandle, tms); 
    tms.ReadIntervalTimeout := 100;//you can change multipler values with 
    tms.ReadTotalTimeoutMultiplier := 100;//your values 
    tms.ReadTotalTimeoutConstant := 1; 
    SetCommTimeOuts(fhandle, tms); 
    End; 
    EscapeCommFunction(fhandle, CLRRTS Or CLRDTR Or SETRTS Or SETDTR);//for handshaking 
    Result := True; 
Except 
    Result := False; 
End; 
End; 

使用

var 
    fporthandle:thandle; 
    begin 
    if OpenPort(fporthandle,'\\.\com1') then 
     try 
     writefile(fporthandle,pchar('TEST')...); 
     finally 
     closehandle(fporthandle); 
     end; 
+0

通信設備在創建時正在接收默認的DCB –

+0

@Premature:確實,但可能默認的DCB波特率,奇偶校驗,流量控制等並不完全是OP所需的。最好明確設置這些內容,並使其對用戶可見。當你完成編寫com端口波特率,奇偶校驗,流量控制配置的所有UI的時候,你可以直接下載並使用'TComPort'。 http://sourceforge.net/projects/comport/ –

+0

對不起,從頭開始創建**,我的意思是開放**('CreateFile(OPEN_EXISTING)')。 @Warren P,是的,但默認是用來代替顯式的。 OP只需要預先配置他的端口。順便說一下,這個鏈接似乎是爲我過度工程。 –