串列埠通訊隨筆

2022-04-06 12:55:27 字數 3811 閱讀 3722

之前了做了個串列埠通訊的專案,主要用到 serialport類

這裡主要說說幾個問題

1. 在關閉串列埠的時候軟體容易卡死的問題.

我們在使用serialport類開啟串列埠時候,會開乙個接收資料的執行緒來接收從串列埠傳送過來的資料,也可以開個呼叫serialport類的事件datareceived (我這裡使用後者,自己開啟的執行緒要一直迴圈接收資料,消耗資源)

_serialport = new

serialport()

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

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

'位元組轉換

private function convertbuffer(byval buffer() as byte) as string

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 while

if _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 then

dim 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 if

catch 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列印值...