2013-07-21 50 views
0

我試圖修改Teunis van Beelen的Rs232庫,從輪詢到事件驅動和非重疊以適合我的項目。 RS232 Library串口未讀取完整傳輸

我希望每200毫秒接收一組數據(大約100到200個字符)。

問題我現在所收到的數據是非常不一致的,它是隨機切斷的,並且不完整。

我想的ReadFile()只讀取數據的一個整塊後返回。(或大意的東西)

我覺得這個問題是超時設置,因爲通過改變數字我得到不同的結果,但我只是不能正確地得到它,到目前爲止我的最好結果是將所有超時值設置爲0,並讓ReadFile()預期爲150字節,這樣ReadFile()不會返回,除非它讀取150個字符,這只是在幾次傳輸之後纔會同步,因爲我不知道需要多少數據。

這些都是Teunis代碼輪詢功能的主要變化,除了超時設置,所有其他設置不變:

//Using the EV_RXCHAR flag will notify the thread that a byte arrived at the port 
DWORD dwError = 0; 
//use SetCommMask and WaitCommEvent to see if byte has arrived at the port 
//SetCommMask sets the desired events that cause a notification. 
if(!SetCommMask(Cport[comport_number],EV_RXCHAR)){ 
    printf("SetCommMask Error"); 
    dwError = GetLastError(); 
    // Error setting com mask 
    return FALSE; 
} 
//WaitCommEvent function detects the occurrence of the events. 
DWORD dwCommEvent; 
for(; ;) 
{ 
    //wait for event to happen 
    if (WaitCommEvent(Cport[comport_number],&dwCommEvent,NULL)) 
    { 
     if(ReadFile(Cport[comport_number], buf, 1, (LPDWORD)((void *)&n), NULL)){ 
      //Byte has been read, buf is processed in main 
     } 
     else{ 
      //error occoured in ReadFile call 
      dwError = GetLastError(); 
      break; 
      } 
    else{ 
     //error in WaitCommEvent 
     break; 
    } 

    break; //break after read file 
} 

嘗試2,通過MSDN article on serial com使用DO WHILE循環通過每一個字符建議在緩衝區中,這種方法也沒有產生任何好的結果。

DWORD dwError = 0; 

/* 
Using the EV_RXCHAR flag will notify the thread that a byte arrived at the port 
*/ 
//use SetCommMask and WaitCommEvent to see if byte has arrived at the port 
//SetCommMask sets the desired events that cause a notification. 
if(!SetCommMask(Cport[comport_number],EV_RXCHAR)){ 
    printf("SetCommMask Error"); 
    dwError = GetLastError(); 
    // Error setting com mask 
    return FALSE; 
} 
//WaitCommEvent function detects the occurrence of the events. 
DWORD dwCommEvent; 
for(; ;) 
{ 
    //wait for event to happen 
    if (WaitCommEvent(Cport[comport_number],&dwCommEvent,NULL)) 
    { 
     //Do while loop will cycle ReadFile until bytes-read reach 0, 
     do{ 
     if(ReadFile(Cport[comport_number], buf, size, (LPDWORD)((void *)&n), NULL)){ 
      //Byte has been read, buf is processed in main 
     } 
     else{ 
      //error occoured in ReadFile call 
      dwError = GetLastError(); 
      break; 
      } 
      }while(n); 
     } 
    else{ 
     //error in WaitCommEvent 
     break; 
    } 
    break; //break after read file 
} 

我想知道如果重寫重疊模式的代碼將改善的事情,但我沒有看到的優點,因爲我已經沒有必要多線程。任何建議都會很棒!

謝謝。

+0

你的情況是什麼dwCommEvent價值? – ST3

+0

它預計EV_RXCHAR事件:收到一個字符並將其放入輸入緩衝區。 – EcEng

+3

這只是串口驅動程序的工作方式,它完成了一個ReadFile()請求,用於接收大於0的任意數量的字節。無論接收緩衝區中發生了什麼。解決方法很簡單,只需在循環中調用ReadFile(),直到獲得所需的數字。 –

回答

3

ReadFile無法檢測「數據塊」是什麼。您不應該期望它能夠理解您的數據或該數據的時間。對於這個問題唯一的解決方法是讓你處理它給你的任何東西,用你自己的數據知識把它分成「塊」以便進一步處理。如果你得到一個部分塊保留它,並在下一次讀取時追加它。

沒有必要爲數據調用WaitCommEvent。 ReadFile將等待數據。但給它一個適當大小的緩衝區,並且一次請求多於一個字節。把它稱爲只有一個字節是非常低效的。選擇請求的計數和超時值,以便ReadFile將在可接受的時間內返回,無論是否有數據。

+0

我想你是正確的,我相信通過操縱超時設置我可以檢測到傳輸中的長時間暫停,從而確定數據塊的結束,但我必須理解錯誤的文檔。 – EcEng