zoukankan      html  css  js  c++  java
  • 串行通讯之.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

    在目录 SerialPortc# 目录内。

  • 相关阅读:
    Cobbler学习之一--Fedora17下配置Cobbler安装环境
    linux下 tar解压 gz解压 bz2等各种解压文件使用方法
    linux性能检测工具
    firefox的plugin-container进程关闭方法
    部署额外域控制器,Active Directory
    利用yum下载软件包的三种方法
    HP iLo2 试用序列号
    (转)Linux下root密码丢失和运行级别错误的解决办法
    linux下的5个查找命令
    (转)CentOs上配置samba服务
  • 原文地址:https://www.cnblogs.com/hanford/p/6135470.html
Copyright © 2011-2022 走看看