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() 
    
    说明:打开事先设置好的端口 
    
    示例: 
    
    
    [csharp] view plaincopyprint?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;   
    }   
    
    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
    ")); //获取手机品牌 
    
    读串口: 
    
    函数原型:public byte[] Read(int NumBytes) 
    
    NumBytes 读入缓存数,注意读取来的是字节数组,要实际应用中要进行字符转换 
    
    示例: 
    
    string response = Encoding.ASCII.GetString(ss_port.Read(128)); //读取128个字节缓存 
    
    关闭串口: 
    
    函数原型:ss_port.Close() 
    
    示例: 
    
    ss_port.Close(); 
    
    整合代码: 
    
    
    [csharp] view plaincopyprint?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"));   
    }   
    }   
    }   
      
    }   
    }   
    
    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")); 
    } 
    } 
    } 
    
    } 
    } 
    
    
     
    
    C#中使用SerialPort类实现串口通信
    
    在.NET Framework 2.0中提供了SerialPort类,该类主要实现串口数据通信等。本文章将本人在学习过程中从网络上搜集到的相关信息写出来供大家参考。
    
    下面主要介绍该类的主要属性(表1)和方法(表.2)。
    
    如果需要了解更多的信息请登录http://msdn.microsoft.com/zh-cn/library/system.io.ports.serialport(VS.80).aspx查看。
    
    相关文章
    
    《使用System.IO.Ports读取COM口数据》
    
    http://www.devasp.net/net/articles/display/727.html
    
    
    
    表1                                                      SerialPort类的常用属性
    
    名  称
     说  明
     
    BaseStream
     获取 SerialPort 对象的基础 Stream 对象
     
    BaudRate
     获取或设置串行波特率
     
    BreakState
     获取或设置中断信号状态
     
    BytesToRead
     获取接收缓冲区中数据的字节数
     
    BytesToWrite
     获取发送缓冲区中数据的字节数
     
    CDHolding
     获取端口的载波检测行的状态
     
    CtsHolding
     获取“可以发送”行的状态
     
    DataBits
     获取或设置每个字节的标准数据位长度
     
    DiscardNull
     获取或设置一个值,该值指示 Null 字节在端口和接收缓冲区之间传输时是否被忽略
     
    DsrHolding
     获取数据设置就绪 (DSR) 信号的状态
     
    DtrEnable
     获取或设置一个值,该值在串行通信过程中启用数据终端就绪 (DTR) 信号
     
    Encoding
     获取或设置传输前后文本转换的字节编码
     
    Handshake
     获取或设置串行端口数据传输的握手协议
     
    IsOpen
     获取一个值,该值指示 SerialPort 对象的打开或关闭状态
     
    NewLine
     获取或设置用于解释 ReadLine( )和WriteLine( )方法调用结束的值
     
    Parity
     获取或设置奇偶校验检查协议
     
    
    续表
    
    名  称
     说  明
     
    ParityReplace
     获取或设置一个字节,该字节在发生奇偶校验错误时替换数据流中的无效字节
     
    PortName
     获取或设置通信端口,包括但不限于所有可用的 COM 端口
     
    ReadBufferSize
     获取或设置 SerialPort 输入缓冲区的大小
     
    ReadTimeout
     获取或设置读取操作未完成时发生超时之前的毫秒数
     
    ReceivedBytesThreshold
     获取或设置 DataReceived 事件发生前内部输入缓冲区中的字节数
     
    RtsEnable
     获取或设置一个值,该值指示在串行通信中是否启用请求发送 (RTS) 信号
     
    StopBits
     获取或设置每个字节的标准停止位数
     
    WriteBufferSize
     获取或设置串行端口输出缓冲区的大小
     
    WriteTimeout
     获取或设置写入操作未完成时发生超时之前的毫秒数
     
    
    表2                                                     SerialPort类的常用方法
    
    方 法 名 称
     说  明
     
    Close
     关闭端口连接,将 IsOpen 属性设置为False,并释放内部 Stream 对象
     
    Open
     打开一个新的串行端口连接
     
    Read
     从 SerialPort 输入缓冲区中读取
     
    ReadByte
     从 SerialPort 输入缓冲区中同步读取一个字节
     
    ReadChar
     从 SerialPort 输入缓冲区中同步读取一个字符
     
    ReadLine
     一直读取到输入缓冲区中的 NewLine 值
     
    ReadTo
     一直读取到输入缓冲区中指定 value 的字符串
     
    Write
     已重载。将数据写入串行端口输出缓冲区
     
    WriteLine
     将指定的字符串和 NewLine 值写入输出缓冲区
     
    
    
    使用SerialPort类的方法:
    
    方法一:
    
    首先要添加
    
    using System.IO;
    using System.IO.Ports;
    
    1...在类的内部定义SerialPort com;
    
    2...打开串口
    
                com = new SerialPort();
                com.BaudRate = 115200;
                com.PortName = "COM1";
                com.DataBits = 8;
                com.Open();//打开串口
    
    3...发送数据
    
                Byte[] TxData ={1,2,3,4,5,6,7,8 };
                com.Write(TxData, 0, 8);
    
    4...接收数据
    
         4.1使用事件接收
    
         this.com.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(this.OnDataReceived);
    
    private void OnDataReceived(object sender, SerialDataReceivedEventArgs e)
    
        4.2使用线程接收
    
         接收数据启动一个线程,使其接收。
    
    在类的内部定义
    
            Thread _readThread;
            bool _keepReading;
    
    打开串口后启动线程
    
                _keepReading = true;
                _readThread = new Thread(ReadPort);
                _readThread.Start();
    
    线程函数
    
    [csharp] view plaincopyprint?private void ReadPort()  
    {  
        while (_keepReading)  
        {  
            if (com.IsOpen)  
            {  
                byte[] readBuffer = new byte[com.ReadBufferSize + 1];  
                try  
                {  
                    // If there are bytes available on the serial port,   
                    // Read returns up to "count" bytes, but will not block (wait)   
                    // for the remaining bytes. If there are no bytes available   
                    // on the serial port, Read will block until at least one byte   
                    // is available on the port, up until the ReadTimeout milliseconds   
                    // have elapsed, at which time a TimeoutException will be thrown.   
                    int count = com.Read(readBuffer, 0, com.ReadBufferSize);  
                    String SerialIn = System.Text.Encoding.ASCII.GetString(readBuffer, 0, count);  
                    if (count != 0)  
                        //byteToHexStr(readBuffer);   
                        ThreadFunction(byteToHexStr(readBuffer,count));  
                }  
                catch (TimeoutException) { }  
            }  
            else  
            {  
                TimeSpan waitTime = new TimeSpan(0, 0, 0, 0, 50);  
                Thread.Sleep(waitTime);  
            }  
        }  
    }  
    
            private void ReadPort()
            {
                while (_keepReading)
                {
                    if (com.IsOpen)
                    {
                        byte[] readBuffer = new byte[com.ReadBufferSize + 1];
                        try
                        {
                            // If there are bytes available on the serial port,
                            // Read returns up to "count" bytes, but will not block (wait)
                            // for the remaining bytes. If there are no bytes available
                            // on the serial port, Read will block until at least one byte
                            // is available on the port, up until the ReadTimeout milliseconds
                            // have elapsed, at which time a TimeoutException will be thrown.
                            int count = com.Read(readBuffer, 0, com.ReadBufferSize);
                            String SerialIn = System.Text.Encoding.ASCII.GetString(readBuffer, 0, count);
                            if (count != 0)
                                //byteToHexStr(readBuffer);
                                ThreadFunction(byteToHexStr(readBuffer,count));
                        }
                        catch (TimeoutException) { }
                    }
                    else
                    {
                        TimeSpan waitTime = new TimeSpan(0, 0, 0, 0, 50);
                        Thread.Sleep(waitTime);
                    }
                }
            }
    
    
    
    方法二:使用C#自带的SerialPor控件。
    
    1...在“工具箱”的“组件”中选择SerialPor控件添加。
    
    2...设置串口并打开
    
    serialPort1.PortName = "COM1";
    
    serialPort1.BaudRate = 9600;
    
    serialPort1.Open();
    
    3...写入数据可以使用Write或者下面的函数
    
    serialPort1.WriteLine(str);
    
    4...添加数据接收的事件
    
    private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
    
    
    使用中的一些常见问题
    
    C#中SerialPort类中DataReceived事件GUI实时处理方法(来自wanglei_wan@yahoo.com.cn 的看法)
    MSDN:从 SerialPort 对象接收数据时,将在辅助线程上引发 DataReceived 事件。由于此事件在辅助线程而非主线程上引发,因此尝试修改主线程中的一些元素(如 UI 元素)时会引发线程异常。如果有必要修改主 Form 或 Control 中的元素,必须使用 Invoke 回发更改请求,这将在正确的线程上执行.进而要想将辅助线程中所读到的数据显示到主线程的Form控件上时,只有通过Invoke方法来实现 
    下面是代码实例: 
    
    
    [csharp] view plaincopyprint?private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)  
    {  
       int SDateTemp = this.serialPort1.ReadByte();  
       //读取串口中一个字节的数据   
       this.tB_ReceiveDate.Invoke(     
        //在拥有此控件的基础窗口句柄的线程上执行委托Invoke(Delegate)   
        //即在textBox_ReceiveDate控件的父窗口form中执行委托.   
        new MethodInvoker(              
        /*表示一个委托,该委托可执行托管代码中声明为 void 且不接受任何参数的任何方法。 在对控件的 Invoke    方法进行调用时或需要一个简单委托又不想自己定义时可以使用该委托。*/  
        delegate{                   
        /*匿名方法,C#2.0的新功能,这是一种允许程序员将一段完整代码区块当成参数传递的程序代码编写技术,通过此种方法可  以直接使用委托来设计事件响应程序以下就是你要在主线程上实现的功能但是有一点要注意,这里不适宜处理过多的方法,因为C#消息机制是消息流水线响应机制,如果这里在主线程上处理语句的时间过长会导致主UI线程阻塞,停止响应或响应不顺畅,这时你的主form界面会延迟或卡死      */                     
        this.tB_ReceiveDate.AppendText(SDateTemp.ToString());//输出到主窗口文本控件   
        this.tB_ReceiveDate.Text += " ";}  
        )  
        );  
    }  
    
    private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
       int SDateTemp = this.serialPort1.ReadByte();
       //读取串口中一个字节的数据
       this.tB_ReceiveDate.Invoke(   
    	//在拥有此控件的基础窗口句柄的线程上执行委托Invoke(Delegate)
    	//即在textBox_ReceiveDate控件的父窗口form中执行委托.
    	new MethodInvoker(            
    	/*表示一个委托,该委托可执行托管代码中声明为 void 且不接受任何参数的任何方法。 在对控件的 Invoke 	方法进行调用时或需要一个简单委托又不想自己定义时可以使用该委托。*/
    	delegate{                 
        /*匿名方法,C#2.0的新功能,这是一种允许程序员将一段完整代码区块当成参数传递的程序代码编写技术,通过此种方法可 	以直接使用委托来设计事件响应程序以下就是你要在主线程上实现的功能但是有一点要注意,这里不适宜处理过多的方法,因为C#消息机制是消息流水线响应机制,如果这里在主线程上处理语句的时间过长会导致主UI线程阻塞,停止响应或响应不顺畅,这时你的主form界面会延迟或卡死      */                   
    	this.tB_ReceiveDate.AppendText(SDateTemp.ToString());//输出到主窗口文本控件
    	this.tB_ReceiveDate.Text += " ";}
        )
        );
    }
    
    如何知道当前电脑有哪个串口
    
    在窗体上添加一个comboBox控件。
    
    然后使用comboBox1.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames());  或者
    
    string[] portList = System.IO.Ports.SerialPort.GetPortNames();
                for (int i = 0; i < portList.Length; ++i)
                {
                    string name = portList[i];
                    comboBox1.Items.Add(name);
                }
    
    具体请参考http://msdn.microsoft.com/zh-tw/library/system.io.ports.serialport.getportnames.aspx
    
  • 相关阅读:
    SNP/单核苷酸多态性分析
    非链特异性转录组测序
    什么是转录因子?
    MEME(Motif-based sequence analysis tools)使用说明
    DNA binding motif比对算法
    序列比对那点事儿
    DNA motif 搜索算法总结
    Bioconductor简介
    什么是RNA-Seq (RNA Sequencing)
    TPM、read counts、RPKM/FPKM你选对了吗?
  • 原文地址:https://www.cnblogs.com/cuihongyu3503319/p/3240511.html
Copyright © 2011-2022 走看看