串行通訊之.NET SerialPort異步寫數據


1說明    2

1 為什么需要異步寫數據?    2

2 異步寫數據的代碼    2

3 源代碼    4

 

 

1說明

1 為什么需要異步寫數據?

如下圖所示,以波特率300打開一個串口。

圖1

單擊"同步發送"按鈕,則數據未發送完之前寫數據的函數不會返回。波特率300,每秒大概能發送25個字符,發送500個字符就需要20秒。這20秒之內,整個程序將處於假死狀態。

單擊"異步發送"按鈕,就不會出現假死狀態。

2 異步寫數據的代碼

異步寫數據的代碼如下:

private void btnWriteAsync_Click(object sender, EventArgs e)

{//異步寫

byte[] byt = System.Text.Encoding.Default.GetBytes(txtSend.Text);

if(byt!=null && byt.Length > 0)

{

IntPtr hComm = GetCommHandle(m_sp);

UInt32 w = 0;

m_ov.hEvent = IntPtr.Zero;

m_ov.Internal = IntPtr.Zero;

m_ov.InternalHigh = IntPtr.Zero;

m_ov.Offset = 0;

m_ov.OffsetHigh = 0;

WriteFile(hComm, byt, (UInt32)byt.Length, ref w, ref m_ov);

}

}

要點為:

1GetCommHandle函數獲取.NET SerialPort對象的串口句柄hComm

2)調用WriteFile函數,異步寫數據。

以下是結構OVERLAPPED的聲明、函數WriteFile的聲明、函數GetCommHandle的實現:

[StructLayout(LayoutKind.Sequential,Pack=4)]

public struct OVERLAPPED

{

public IntPtr Internal;

public IntPtr InternalHigh;

public UInt32 Offset;

public UInt32 OffsetHigh;

public IntPtr hEvent;

}

[DllImport("kernel32.dll", SetLastError = true

, CallingConvention = CallingConvention.Winapi)]

private static extern UInt32 WriteFile(IntPtr hFile, byte[] lpBuffer

, UInt32 nNumberOfBytesToWrite

, ref UInt32 lpNumberOfBytesWritten

, ref OVERLAPPED lpOverlapped);

 

protected System.IO.Ports.SerialPort m_sp =

new System.IO.Ports.SerialPort();

protected OVERLAPPED m_ov;

 

static IntPtr GetCommHandle(System.IO.Ports.SerialPort sp)

{//獲得串口句柄,供 Win32 API 使用

IntPtr hComm = IntPtr.Zero;

if (sp != null)

{

object stream = typeof(System.IO.Ports.SerialPort).GetField("internalSerialStream", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetValue(sp);

var handle = (Microsoft.Win32.SafeHandles.SafeFileHandle)stream.GetType().GetField("_handle", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetValue(stream);

hComm = handle.DangerousGetHandle();

}

return hComm;

}

3 源代碼

本文的代碼已上傳至git服務器:

https://github.com/hanford77/Exercise

https://git.oschina.net/hanford/Exercise

在目錄 SerialPort\c# 目錄內。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM