zoukankan      html  css  js  c++  java
  • [转]在C#中实现串口通信

    本文主要是讲述如何通过C# .net1.1平台调用API操作串口,.net2.0已经内置串口操作类!


    通常,在C#中实现串口通信,我们有四种方法:

    第一:通过MSCOMM控件这是最简单的,最方便的方法。可功能上很难做到控制自如,同时这个控件并不是系统本身所带,所以还得注册。可以访问
    http://www.devhood.com/tutorials/tutorial_details.aspx?tutorial_id=320

    一个外国人写的教程

    第二:微软在.NET新推出了一个串口控件,基于.NET的P/Invoke调用方法实现,详细的可以访问微软网站

    Serial Comm
    Use P/Invoke to Develop a .NET Base Class Library for Serial
    Device Communications

    http://msdn.microsoft.com/msdnmag/issues/02/10/netserialcomm/

    第三:就是用第三方控件啦,可一般都要付费的,不太合实际,何况楼主不喜欢,不作考虑

    第四:自己用API写串口通信,这样难度高点,但对于我们来说,可以方便实现自己想要的各种功能。


    我们采用第四种方法来实现串口通信,用现成的已经封装好的类库,常见两个串口操作类是JustinIO和SerialStreamReader。介绍JustinIO的使用方法:


    打开串口:

    函数原型:public void Open()

    说明:打开事先设置好的端口

    示例:


    using JustinIO;

    static JustinIO.CommPort ss_port = new
    JustinIO.CommPort();
    ss_port.PortNum = COM1; //端口号
    ss_port.BaudRate =
    19200; //串口通信波特率
    ss_port.ByteSize = 8; //数据位
    ss_port.Parity = 0; //奇偶校验

    ss_port.StopBits = 1;//停止位
    ss_port.ReadTimeout = 1000; //读超时
    try

    {
    if (ss_port.Opened)
    {
    ss_port.Close();
    ss_port.Open();
    //打开串口
    }
    else
    {
    ss_port.Open();//打开串口
    }
    return true;

    }
    catch(Exception e)
    {
    MessageBox.Show("错误:" + e.Message);

    return false;
    }

    写串口:

    函数原型:public void Write(byte[]
    WriteBytes)

    WriteBytes 就是你的写入的字节,注意,字符串要转换成字节数组才能进行通信

    示例:


    ss_port.Write(Encoding.ASCII.GetBytes("AT+CGMI\r")); //获取手机品牌


    读串口:

    函数原型:public byte[] Read(int NumBytes)

    NumBytes
    读入缓存数,注意读取来的是字节数组,要实际应用中要进行字符转换

    示例:

    string response =
    Encoding.ASCII.GetString(ss_port.Read(128)); //读取128个字节缓存

    关闭串口:


    函数原型:ss_port.Close()

    示例:

    ss_port.Close();

    整合代码:

    using System;
    using System.Runtime.InteropServices;

    namespace
    JustinIO {
    class CommPort {

    public int PortNum;
    public int
    BaudRate;
    public byte ByteSize;
    public byte Parity; //
    0-4=no,odd,even,mark,space
    public byte StopBits; // 0,1,2 = 1, 1.5, 2

    public int ReadTimeout;

    //comm port win32 file handle
    private
    int hComm = -1;

    public bool Opened = false;

    //win32 api
    constants
    private const uint GENERIC_READ = 0x80000000;
    private const
    uint GENERIC_WRITE = 0x40000000;
    private const int OPEN_EXISTING = 3;

    private const int INVALID_HANDLE_VALUE = -1;


    [StructLayout(LayoutKind.Sequential)]
    public struct DCB {

    //taken from c struct in platform sdk
    public int DCBlength; //
    sizeof(DCB)
    public int BaudRate; // current baud rate
    /* these are the c
    struct bit fields, bit twiddle flag to set
    public int fBinary; // binary
    mode, no EOF check
    public int fParity; // enable parity checking
    public
    int fOutxCtsFlow; // CTS output flow control
    public int fOutxDsrFlow; // DSR
    output flow control
    public int fDtrControl; // DTR flow control type

    public int fDsrSensitivity; // DSR sensitivity
    public int
    fTXContinueOnXoff; // XOFF continues Tx
    public int fOutX; // XON/XOFF out
    flow control
    public int fInX; // XON/XOFF in flow control
    public int
    fErrorChar; // enable error replacement
    public int fNull; // enable null
    stripping
    public int fRtsControl; // RTS flow control
    public int
    fAbortOnError; // abort on error
    public int fDummy2; // reserved
    */

    public uint flags;
    public ushort wReserved; // not currently used

    public ushort XonLim; // transmit XON threshold
    public ushort XoffLim;
    // transmit XOFF threshold
    public byte ByteSize; // number of bits/byte, 4-8

    public byte Parity; // 0-4=no,odd,even,mark,space
    public byte StopBits;
    // 0,1,2 = 1, 1.5, 2
    public char XonChar; // Tx and Rx XON character

    public char XoffChar; // Tx and Rx XOFF character
    public char ErrorChar;
    // error replacement character
    public char EofChar; // end of input
    character
    public char EvtChar; // received event character
    public ushort
    wReserved1; // reserved; do not use
    }


    [StructLayout(LayoutKind.Sequential)]
    private struct COMMTIMEOUTS {

    public int ReadIntervalTimeout;
    public int ReadTotalTimeoutMultiplier;

    public int ReadTotalTimeoutConstant;
    public int
    WriteTotalTimeoutMultiplier;
    public int WriteTotalTimeoutConstant;
    }


    [StructLayout(LayoutKind.Sequential)]
    private struct OVERLAPPED {

    public int Internal;
    public int InternalHigh;
    public int Offset;

    public int OffsetHigh;
    public int hEvent;
    }


    [DllImport("kernel32.dll")]
    private static extern int CreateFile(

    string lpFileName, // file name
    uint dwDesiredAccess, // access mode

    int dwShareMode, // share mode
    int lpSecurityAttributes, // SD
    int
    dwCreationDisposition, // how to create
    int dwFlagsAndAttributes, // file
    attributes
    int hTemplateFile // handle to template file
    );

    [DllImport("kernel32.dll")]
    private static extern bool GetCommState(

    int hFile, // handle to communications device
    ref DCB lpDCB //
    device-control block
    );
    [DllImport("kernel32.dll")]
    private static
    extern bool BuildCommDCB(
    string lpDef, // device-control string
    ref DCB
    lpDCB // device-control block
    );
    [DllImport("kernel32.dll")]
    private
    static extern bool SetCommState(
    int hFile, // handle to communications
    device
    ref DCB lpDCB // device-control block
    );

    [DllImport("kernel32.dll")]
    private static extern bool GetCommTimeouts(

    int hFile, // handle to comm device
    ref COMMTIMEOUTS lpCommTimeouts //
    time-out values
    );
    [DllImport("kernel32.dll")]
    private static extern
    bool SetCommTimeouts(
    int hFile, // handle to comm device
    ref
    COMMTIMEOUTS lpCommTimeouts // time-out values
    );

    [DllImport("kernel32.dll")]
    private static extern bool ReadFile(
    int
    hFile, // handle to file
    byte[] lpBuffer, // data buffer
    int
    nNumberOfBytesToRead, // number of bytes to read
    ref int
    lpNumberOfBytesRead, // number of bytes read
    ref OVERLAPPED lpOverlapped //
    overlapped buffer
    );
    [DllImport("kernel32.dll")]
    private static
    extern bool WriteFile(
    int hFile, // handle to file
    byte[] lpBuffer, //
    data buffer
    int nNumberOfBytesToWrite, // number of bytes to write
    ref
    int lpNumberOfBytesWritten, // number of bytes written
    ref OVERLAPPED
    lpOverlapped // overlapped buffer
    );
    [DllImport("kernel32.dll")]

    private static extern bool CloseHandle(
    int hObject // handle to object

    );
    [DllImport("kernel32.dll")]
    private static extern uint
    GetLastError();

    public void Open() {

    DCB dcbCommPort = new
    DCB();
    COMMTIMEOUTS ctoCommPort = new COMMTIMEOUTS();


    // OPEN
    THE COMM PORT.


    hComm = CreateFile("COM" + PortNum ,GENERIC_READ |
    GENERIC_WRITE,0, 0,OPEN_EXISTING,0,0);

    // IF THE PORT CANNOT BE OPENED,
    BAIL OUT.
    if(hComm == INVALID_HANDLE_VALUE) {
    throw(new
    ApplicationException("Comm Port Can Not Be Opened"));
    }

    // SET THE
    COMM TIMEOUTS.

    GetCommTimeouts(hComm,ref ctoCommPort);

    ctoCommPort.ReadTotalTimeoutConstant = ReadTimeout;

    ctoCommPort.ReadTotalTimeoutMultiplier = 0;

    ctoCommPort.WriteTotalTimeoutMultiplier = 0;

    ctoCommPort.WriteTotalTimeoutConstant = 0;
    SetCommTimeouts(hComm,ref
    ctoCommPort);

    // SET BAUD RATE, PARITY, WORD SIZE, AND STOP BITS.

    GetCommState(hComm, ref dcbCommPort);
    dcbCommPort.BaudRate=BaudRate;

    dcbCommPort.flags=0;
    //dcb.fBinary=1;
    dcbCommPort.flags|=1;
    if
    (Parity>0)
    {
    //dcb.fParity=1
    dcbCommPort.flags|=2;
    }

    dcbCommPort.Parity=Parity;
    dcbCommPort.ByteSize=ByteSize;

    dcbCommPort.StopBits=StopBits;
    if (!SetCommState(hComm, ref
    dcbCommPort))
    {
    //uint ErrorNum=GetLastError();
    throw(new
    ApplicationException("Comm Port Can Not Be Opened"));
    }
    //unremark to
    see if setting took correctly
    //DCB dcbCommPort2 = new DCB();

    //GetCommState(hComm, ref dcbCommPort2);
    Opened = true;

    }


    public void Close() {
    if (hComm!=INVALID_HANDLE_VALUE) {

    CloseHandle(hComm);
    }
    }
    public byte[] Read(int NumBytes) {

    byte[] BufBytes;
    byte[] OutBytes;
    BufBytes = new byte[NumBytes];

    if (hComm!=INVALID_HANDLE_VALUE) {
    OVERLAPPED ovlCommPort = new
    OVERLAPPED();
    int BytesRead=0;
    ReadFile(hComm,BufBytes,NumBytes,ref
    BytesRead,ref ovlCommPort);
    OutBytes = new byte[BytesRead];

    Array.Copy(BufBytes,OutBytes,BytesRead);
    }
    else {
    throw(new
    ApplicationException("Comm Port Not Open"));
    }
    return OutBytes;
    }


    public void Write(byte[] WriteBytes) {
    if
    (hComm!=INVALID_HANDLE_VALUE) {
    OVERLAPPED ovlCommPort = new OVERLAPPED();

    int BytesWritten = 0;
    WriteFile(hComm,WriteBytes,WriteBytes.Length,ref
    BytesWritten,ref ovlCommPort);
    }
    else {
    throw(new
    ApplicationException("Comm Port Not Open"));
    }
    }
    }

    }
    }


    由于篇幅,以及串口通信涉及内容广泛,我在这里只讲这些。

  • 相关阅读:
    032 Gradle 下载的依赖jar包在哪?
    031 can't rename root module,Android Studio修改项目名称
    030 Cannot resolve symbol'R' 问题解决汇总大全
    029 Android Studio层级显示目录文件
    028 You are about to commit CRLF line separators to the Git repository.It is recommended to set the core. autocrlf Git attribute to true to avoid line separator issues If you choose Fix and Comit ,
    027 【Android基础知识】Android Studio 编译慢及 Adb connection Error:远程主机强迫关闭了一个现有的连接
    026 Android Studio 和Gradle版版本对应关系
    025 Cause: org.jetbrains.plugins.gradle.tooling.util.ModuleComponentIdentifierIm
    024 Android Studio上传项目到Github 最全记录
    023 解决AndroidStudio下载gradle慢的问题
  • 原文地址:https://www.cnblogs.com/rongxiaoya/p/2867905.html
Copyright © 2011-2022 走看看