2014-09-01 32 views
2

我想發送一些十六進制字符串到串口,並直接閱讀它的答案在c + +。如果沒有答案,它應該在一段時間後超時。寫入和讀取/從一個串口在c + +和Linux的超時

  • 這樣的任務最簡單的實現是什麼?
  • 我需要使用類似提升的東西嗎?

要清楚:我正在尋找最簡單的方法來實現這一點。

對不起,如果我的問題是愚蠢的,但即時通訊新的這個話題,在此先感謝!

編輯:對不起,我忘了提及,它應該在Linux上運行。

+0

閱讀:http://members.ee.net/brey/Serial.pdf – jbutler483 2014-09-01 08:04:40

+0

好吧,好的,但是,如它的文件寫入:如果沒有收到數據,此功能將掛起,因爲沒有超時設置。 - 我認爲那是我最大的問題。 – p0fi 2014-09-01 08:11:42

+0

請看我的編輯(在回答) – jbutler483 2014-09-01 08:14:01

回答

1

這應該是類似的聲明:

Setup(CSerial::EBaud9600,CSerial::EData8,CSerial::EParNone,CSerial::EStop1); 

Setup(CSerial::EBaudrate(9600), 
     CSerial::EDataBits(8), 
     CSerial::EParity(NOPARITY), 
     CSerial::EStopBits(ONESTOPBIT)); 

讀取數據:

// Read data, until there is nothing left 
    DWORD dwBytesRead = 0; 
    BYTE abBuffer[100]; 
    do 
    { 
     // Read data from the COM-port 
     serial.Read(abBuffer,sizeof(abBuffer),&dwBytesRead); 
     if (dwBytesRead > 0) 
     { 
      // TODO: Process the data 
     } 
    } 
    while (dwBytesRead == sizeof(abBuffer)); 

更多細節可以在這裏找到的代碼項目:http://www.codeproject.com/Articles/992/Serial-library-for-C

請注意:我我習慣在c#中編程串口,所以(據我所知)相信這對你有用。 (我也想指出outall串口通信是通過爲十六進制實際發送,但可以通過緩衝區作爲十進制值讀取(請參閱http://www.asciitable.com/爲converstion,或使用類似UTF8編碼的東西)

編輯 - 作爲根據註釋;

請參考:http://msdn.microsoft.com/en-gb/library/windows/hardware/hh439614(v=vs.85).aspx串行端口的詳細信息的讀/寫超時

寫超時將類似於;

[BrowsableAttribute(true)] 
public: 
property int WriteTimeout { 
    int get(); 
    void set (int value); 
} 

它允許你獲取或設置超時屬性

完整程序

public: 
    static void Main() 
    { 
     String^ name; 
     String^ message; 
     StringComparer^ stringComparer = StringComparer::OrdinalIgnoreCase; 
     Thread^ readThread = gcnew Thread(gcnew ThreadStart(PortChat::Read)); 

     // Create a new SerialPort object with default settings. 
     _serialPort = gcnew SerialPort(); 

     // Allow the user to set the appropriate properties. 
     _serialPort->PortName = SetPortName(_serialPort->PortName); 
     _serialPort->BaudRate = SetPortBaudRate(_serialPort->BaudRate); 
     _serialPort->Parity = SetPortParity(_serialPort->Parity); 
     _serialPort->DataBits = SetPortDataBits(_serialPort->DataBits); 
     _serialPort->StopBits = SetPortStopBits(_serialPort->StopBits); 
     _serialPort->Handshake = SetPortHandshake(_serialPort->Handshake); 

     // Set the read/write timeouts 
     _serialPort->ReadTimeout = 500; 
     _serialPort->WriteTimeout = 500; 

     _serialPort->Open(); 
     _continue = true; 
     readThread->Start(); 

     Console::Write("Name: "); 
     name = Console::ReadLine(); 

     Console::WriteLine("Type QUIT to exit"); 

     while (_continue) 
     { 
      message = Console::ReadLine(); 

      if (stringComparer->Equals("quit", message)) 
      { 
       _continue = false; 
      } 
      else 
      { 
       _serialPort->WriteLine(
        String::Format("<{0}>: {1}", name, message)); 
      } 
     } 

     readThread->Join(); 
     _serialPort->Close(); 
    } 

    static void Read() 
    { 
     while (_continue) 
     { 
      try 
      { 
       String^ message = _serialPort->ReadLine(); 
       Console::WriteLine(message); 
      } 
      catch (TimeoutException ^) { } 
     } 
    } 

EDIT 2

請參考Linux Serial Port: Blocking Read with Timeout,其中這在問題被宣佈和一些答案也許對你有用! :)

+0

以及這一切看起來很像我可以在Windows上使用它嗎?對不起,我忘了提及它應該用在Linux系統上,我相應地更新了我的問題。 – p0fi 2014-09-01 08:17:56

1

我最近來到相同的問題,我發現一個很好的解決方案,使用select() 閱讀文檔在這裏:manpages.courirer-mta.org/htmlman2/select2。HTML

你的情況,你需要設置超時,這是選擇第五說法:

struct timeval timeout; 

    timeout.tv_sec = 0 ; // seconds 

    timeout.tv_usec = 1000 ; // microseconds 

希望這有助於。