源:串口通信中ReadFile和WriteFile的超時詳解!
在用ReadFile和WriteFile讀寫串行口時,需要考慮超時問題。如果在指定的時間內沒有讀出或寫入指定數量的字符,那么ReadFile或WriteFile的操作就會結束。要查詢當前的超時設置應調用GetCommTimeouts函數,該函數會填充一個COMMTIMEOUTS結構。調用SetCommTimeouts可以用某一個COMMTIMEOUTS結構的內容來設置超時。 有兩種超時:間隔超時和總超時。間隔超時是指在接收時兩個字符之間的最大時延,總超時是指讀寫操作總共花費的最大時間。寫操作只支持總超時,而讀操作兩種超時均支持。
typedef struct _COMMTIMEOUTS { DWORD ReadIntervalTimeout; // 讀間隔超時。 接收時,兩字符間最大的時延。 DWORD ReadTotalTimeoutMultiplier; // 讀時間系數。 讀取每字節的超時。 DWORD ReadTotalTimeoutConstant; // 讀時間常量。 讀串口數據的固定超時。 // 總超時 = ReadTotalTimeoutMultiplier * 字節數 + ReadTotalTimeoutConstant DWORD WriteTotalTimeoutMultiplier;// 寫時間系數。 寫每字節的超時。 DWORD WriteTotalTimeoutConstant; // 寫時間常量。 寫串口數據的固定超時。 // 總超時 = WriteTotalTimeoutMultiplier * 字節數 + WriteTotalTimeoutConstant } COMMTIMEOUTS,*LPCOMMTIMEOUTS;
COMMTIMEOUTS//COMMTIMEOUTS對象 SetCommTimeouts(handlePort_,&comTimeOut);//;將超時參數寫入設備控制
ReadIntervalTimeout:
指定通訊線上兩個字符到達的最大時延,以毫秒為單位。在ReadFile操作期間,時間周期從第一個字符接收到算起。如果收到的兩個字符之間的間隔超過該值,ReadFile操作完畢並返回所有緩沖數據。如果ReadIntervalTimeout為0,則該值不起作用。
如果值為MAXDWORD, 並且ReadTotalTimeoutConstant和ReadTotalTimeoutMultiplier兩個值都為0, 則指定讀操作攜帶已經收到的字符立即返回,即使沒有收到任何字符。
ReadTotalTimeoutMultiplier:
指定以毫秒為單位的累積值。用於計算讀操作時的超時總數。對於每次讀操作,該值與所要讀的字節數相乘。
ReadTotalTimeoutConstant :
指定以毫秒為單位的常數。用於計算讀操作時的超時總數。對於每次讀操作,ReadTotalTimeoutMultiplier與所要讀的字節數相乘后與該值相加。
如果ReadTotalTimeoutMultiplier和ReadTotalTimeoutConstant都為0,則在讀操作時忽略總超時數。
WriteTotalTimeoutMultiplier:
指定以毫秒為單位的累積值。用於計算寫操作時的超時總數。對於每次寫操作,該值與所要寫的字節數相乘。
WriteTotalTimeoutConstant:
指定以毫秒為單位的常數。用於計算寫操作時的超時總數。對於每次寫操作,WriteTotalTimeoutMultiplier與所要寫的字節數相乘后與該值相加。
如果WriteTotalTimeoutMultiplier和WriteTotalTimeoutConstant都為0,則在寫操作時忽略總超時數。
提示:用戶設置通訊超時后,如沒有出錯,串口已經被打開。
COMMTIMEOUTS結構的成員都以毫秒為單位。
總超時的計算公式是:
總超時 = 時間系數 × 要求讀/寫的字符數 + 時間常量
例如,如果要讀入10個字符,那么讀操作的總超時的計算公式為:
讀總超時 = ReadTotalTimeoutMultiplier × 10 + ReadTotalTimeoutConstant
可以看出,間隔超時和總超時的設置是不相關的,這可以方便通信程序靈活地設置各種超時。如果所有寫超時參數均為0,那么就不使用寫超時。如果ReadIntervalTimeout為0,那么就不使用讀間隔超時,如果ReadTotalTimeoutMultiplier和ReadTotalTimeoutConstant都為0,則不使用讀總超時。如果讀間隔超時被設置成MAXDWORD並且兩個讀總超時為0,那么在讀一次輸入緩沖區中的內容后讀操作就立即完成,而不管是否讀入了要求的字符。 在用重疊方式讀寫串行口時,雖然ReadFile和WriteFile在完成操作以前就可能返回,但超時仍然是起作用的。在這種情況下,超時規定的是操作的完成時間,而不是ReadFile和WriteFile的返回時間。
