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"));
    }
    }
    }

    }
    }


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

  • 相关阅读:
    requirejs实现对动态combo的支持
    遇见Javascript类型数组(Typed Array)
    【转发】2012年HTML5的14个大胆预言
    跟我学canvas(三,应用图像)
    贡献一个连jquery都觉的大的时候可以用的 js库
    websocket终成标准
    Django中的form不足之处
    Eclipse+Pydev 开发Django中的Debug模式
    Javascript中指定周末日期的计算
    Python中递归的最大次数
  • 原文地址:https://www.cnblogs.com/rongxiaoya/p/2867905.html
Copyright © 2011-2022 走看看