本人在程式中要用到串口,在處理串口的程序中碰到一個令我感到極為疑惑的現象,希望有知道的大俠指點一下!
下面我將問題詳細描述一下:處理串口的方式我參考了CSerialPort類,因為感覺CSerialPort類在接收方面效率較低,又不好怎么處理modbus rtu類的協議,所以我將接收方面做了修改,另外寫串口沒有在執行緒函式內。具體思路是:初始化串口后,建立讀監視執行緒,呼叫WaitCommEvent函式,如果函式回傳FALSE,呼叫GetLastError,如果為IO_PENDING,轉入WaitForSingleObject后續處理,如果是其他,報錯處理。如果WaitCommEvent回傳TRUE,呼叫ClearCommError看cbInQue,如果為0,continue(和CSerialPort同)。接下來WaitForSingleObject阻塞執行緒等待,如果為OBJECT_0,呼叫接收函式RecvChar處理,RecvChar處理和CSerialPort有點不同,具體是在for(;;)中每次讀1個字符,一直讀緩沖區,直到cbInQue為0,再用Sleep等待5ms,如果確實無后續字符到達,結束接收并發送訊息。(由于斷定呼叫RecvChar時cbInQue肯定不為0,因為為0時監視執行緒continue掉了,同時后續的處理用到了即使為0仍等待5ms才判斷結束,所以一開始沒有cbInQue== 0的判斷)。
我的問題是,當我在一收一發的應用中,發現當我發送一幀查詢命令,程式收到了兩次通知接收的訊息。第一條訊息后,資料全部被接收,是完整的,第二次接收長度為0。按照程式的設想,在RecvChar處理程序中,后續字符可能到達,并置位EV_RXCHAR,和WaitForSingleObject中的事件,當從RecvChar回傳監視執行緒,WaitCommEvent應該回傳TRUE,并continue掉,根本不會發出第二條通知接收的訊息。但是情況是第二條訊息確實發出了。我猜測除非是這樣一種情況:在呼叫RecvChar處理接收時,每呼叫一次ReadFile系統都清除一次EV_RXCHAR,由于在WINDOWS中EV_RXCHAR產生的次數總是等于或比接收到的字符數少(這點和單片機不同),這樣在RecvChar回傳時已經沒有EV_RXCHAR了,只有WaitForSingleObject中的事件了(ReadFile并不復位這一事件)。再回傳監視執行緒時,呼叫WaitCommEvent結果是FALSE,轉入WaitForSingleObject處理,觸發了第二次讀,因為緩沖區沒有字符,所以僅觸發了一次接收訊息。由于沒有找到EV_RXCHAR觸發,復位的相關資訊,所以不知道自己的猜測對不對,還望知道的回復一下!
uj5u.com熱心網友回復:
搜“Xon Xoff”uj5u.com熱心網友回復:
我說的跟流控沒多大關系吧,我沒有用到這個uj5u.com熱心網友回復:
建議使用CxSerial類http://www.cnblogs.com/EdmundDwyane/p/3161524.html
uj5u.com熱心網友回復:
串口收發,俺習慣發送---主動呼叫
接收---執行緒接收
在主程式中不停的判斷某一幀是否接收完成。
使用多級大緩沖,一級只管接收,回圈緩沖區,大小為2^n位元組,一般為64K位元組,用一個unsigned short的變數當成寫入下標。
for( 本次接收的數量 )
buffer_level_1[ io_read++ ] = 本次接收的字符[ i ];
1級存放完整的資料
根據業務要求,再設定2級,或3級緩沖,有時發送一條,會收到多條回應,那么2級中就會存放分成幀的資料,一般還是在執行緒中進行分幀,只要io_read與io_recv不一致,則在執行緒中不停的等待。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/150788.html
標籤:硬件/系統
上一篇:MFC中的一個問題
