之前了做了個串列埠通訊的專案,主要用到 serialport類
這裡主要說說幾個問題
1. 在關閉串列埠的時候軟體容易卡死的問題.
我們在使用serialport類開啟串列埠時候,會開乙個接收資料的執行緒來接收從串列埠傳送過來的資料,也可以開個呼叫serialport類的事件datareceived (我這裡使用後者,自己開啟的執行緒要一直迴圈接收資料,消耗資源)
_serialport = newserialport()
addhandler _serialport.datareceived, addressof serialport_datareceived '
新增串列埠接收資料事件
private
sub serialport_datareceived(byval sender as
object, byval e as
system.io.ports.serialdatareceivedeventargs)'
'這裡寫接收資料的處理
'end sub
在寫好接收資料處理的方法後, 我們來看看具體的處理方法
private delegate sub delshowmessage(byval msg as string) '定義乙個帶字串引數的委託private function convertbuffer(byval buffer() as byte) as stringprivate
sub serialport_datareceived(byval sender as
object, byval e as
system.io.ports.serialdatareceivedeventargs)
dim bytestoread as
integer =_serialport.bytestoread
if bytestoread = 0
then
exit sub
endif
'定義位元組陣列接收資料
dim buffer(bytestoread - 1) as
byte
'讀取緩衝區資料到位元組陣列中
_serialport.read(buffer,
0, bytestoread)
'把位元組轉成相應的字串 (這裡只是個demo 真正的專案接收的位元組都是有自己的協議進行轉換的)
dim messagestr as
string =convertbuffer(buffer)
'接收資料這個方法是個執行緒,用委託來處理顯示
me.invoke(new
delshowmessage(addressof showmessage),messagestr)
end sub
『在文字框中顯示字串
private
sub showmessage(byval message as
string
)
textbox1.text=message
end sub
'位元組轉換
return bitconverter.tostring(buffer)
end function
上段**將接收到的資料轉換成字串顯示到文字框中
下面是關閉埠的方法
'關閉埠方法private sub btnportclose_click(byval sender as system.object, byval e as system.eventargs) handles btnportclose.click
if _serialport.isopen = true then
_serialport.close()
end if
end sub
就是這樣直接關閉埠, 有時候軟體會卡死
找到原因: 在點選按鈕關閉埠的時候, 關閉這個方法在ui執行緒中執行, 如果串列埠接收的資料正好也需要用委託ui執行緒, 這樣操作的的時候, 會結束這個接收的方法,如果這個方法同樣在操作ui執行緒,就會造成死鎖.
改進的方法:1. 在接收的資料的時候加乙個標誌說明已經有資料在處理,資料處理結束將此標誌恢復, 在點選按鈕關閉串列埠的時候, 等待這個標誌恢復,再去關閉這個串列埠.
在點選按鈕關閉串列埠的時候同樣加乙個標誌說明需要關閉串列埠, 接收資料的時候判斷是否有此標誌, 有此標誌則不進行處理
2. 是比較簡單的方法, 在處理完資料介面顯示的用非同步委託
第一種方法:
'監聽介面是否更新資料'關閉埠方法
private _bclosing as boolean = false
private _blistening as boolean = false
private
sub btnportclose_click(byval sender as system.object, byval e as system.eventargs) handles
btnportclose.click
'新增關閉標誌,說明在關閉串列埠
_bcloseing = true
while (_blistening)
end whileif _serialport.isopen = true
then
_serialport.close()endif
_bcloseing = false
end sub
private sub serialport_datareceived(byval sender as object, byval e assystem.io.ports.serialdatareceivedeventargs)'監聽埠是否關閉if _bcloing = true then
exit sub
end if
try
_blistening = true
if _serialport.isopen = true thendim bytestoread as integer = _serialport.bytestoread()
if bytestoread=0 then
exit sub
end
'定義位元組陣列接收資料dim buffer(bytestoread - 1) as byte
'讀取緩衝區資料到位元組陣列中
_serialport.read(buffer, 0, bytestoread)
'把位元組轉成相應的字串 (這裡只是個demo 真正的專案接收的位元組都是有自己的協議進行轉換的)
dim messagestr as string =convertbuffer(buffer)
'接收資料這個方法是個執行緒,用委託來處理顯示
me.invoke(newdelshowmessage(addressof showmessage),messagestr)
end ifcatch ex as exception
finally
_blistening = false
end try
end sub
第二種方法:
將委託的那部分用非同步委託代替
me.begininvoke(new delshowmessage(addressof showmessage),messagestr)
串列埠通訊 串列埠通訊原理
1 rs232介面 rs232 c介面聯結器一般使用型號為db 9的9芯插頭座,只需3條介面線,即 傳送資料 接收資料 和 訊號地 即可傳輸資料,其9個引腳的定義如圖11 3所示。圖11 3 rs232 c介面聯結器定義 在rs232的規範中,電壓值在 3v 15v 一般使用 6v 稱為 0 或 o...
串列埠同步通訊和串列埠非同步通訊
串列埠掃盲貼 現實中不存在絕對精確的時鐘,標稱值同樣是1mhz,發端和接收端的時鐘總會存在差異,如果接收端不進行時鐘同步,而是使用自己本地的時鐘,則足夠長的時間後接收到的資料總會出現不可預知的重複或丟失,導致接收錯誤。因此發端必須將與資料速率相關的時鐘訊號傳輸給接收端,時鐘訊號可以走單獨的訊號線,也...
Socket通訊隨筆
1 伺服器與同乙個客戶端可以同時建立多個socket,而且每個socket有唯一標識。如python程式1與python程式2同時建立多個socket 實驗結果如下 注意 上面兩張圖為同一次輸出結果,圖太大了,分兩次截。上面的,顯示了python程式1接收到的三次socket連線的socket列印值...