在C#中实现串口通信的方法

清华大佬耗费三个月吐血整理的几百G的资源,免费分享!....>>>

    通常,在C#中实现串口通信,我们有四种方法:  
    第一:通过MSCOMM控件这是最简单的,最方便的方法。可功能上很难做到控制自如,同时这个控件并不是系统本身所带,所以还得注册,不在本文讨论范围。可以访问http://www.devhood.com/tutorials/tutorial_details.aspx?tutorial_id=320 ,一个国外网友的写的教程,作者很热心,我曾有发邮件给他,很快就回复了。  
      
    第二:微软在.NET新推出了一个串口控件,基于.NET的P/Invoke调用方法实现,详细的大家可以访问微软网站http://msdn.microsoft.com/msdnmag/issues/02/10/NETSerialComm/default.aspx,方便得到更多资料。  
      
    第三:就是用第三方控件啦,可一般都要付费的,不太合实际,不作考虑  
      
    第四:自己用API写串口通信,这样难度高点,但对于我们来说,可以方便实现自己想要的各种功能  
      
    在本文,我们采用第四种方法来实现串口通信,不过不是自己写,用一个国外网友现成的已经封装好的类库,不过功能简单点,相对我们来说已经够用了。  
      
    在整个终端短信的操作过程中,与串口的通信,只用到了四个功能,打开、写、读、关闭串口。下面是类库对这四个功能的定义:  
      
    打开串口:  
      
    函数原型: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 BusApp  
    {  
     /// <summary>  
     ///   
     /// </summary>  
     public class mycom  
     {  
      public mycom()  
      {  
       //   
       // TODO: 在此处添加构造函数逻辑  
       //  
      }  
      public int PortNum; //1,2,3,4  
      public int BaudRate; //1200,2400,4800,9600  
      public byte ByteSize; //8 bits  
      public byte Parity; // 0-4=no,odd,even,mark,space   
      public byte StopBits; // 0,1,2 = 1, 1.5, 2   
      public int ReadTimeout; //10  
        
      //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)]  
       private struct DCB   
      {  
       //taken from c struct in platform sdk   
       public int DCBlength;           // sizeof(DCB)   
       public int BaudRate;            // current baud rate   
       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 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  
       );  
        
      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.  
       // THERE ARE OTHER WAYS OF DOING SETTING THESE BUT THIS IS THE EASIEST.  
       // IF YOU WANT TO LATER ADD CODE FOR OTHER BAUD RATES, REMEMBER  
       // THAT THE ARGUMENT FOR BuildCommDCB MUST BE A POINTER TO A STRING.  
       // ALSO NOTE THAT BuildCommDCB() DEFAULTS TO NO HANDSHAKING.  
        
       dcbCommPort.DCBlength = Marshal.SizeOf(dcbCommPort);  
       GetCommState(hComm, ref dcbCommPort);  
       dcbCommPort.BaudRate=BaudRate;  
       dcbCommPort.Parity=Parity;  
       dcbCommPort.ByteSize=ByteSize;  
       dcbCommPort.StopBits=StopBits;  
       SetCommState(hComm, ref dcbCommPort);  
          
       Opened = true;  
          
      }  
        
      public void Close()   
      {  
       if (hComm!=INVALID_HANDLE_VALUE)   
       {  
        CloseHandle(hComm);  
                    Opened=false;  
       }  
      }  
        
      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 int Write(byte[] WriteBytes)   
      {  
       int BytesWritten = 0;  
       if (hComm!=INVALID_HANDLE_VALUE)   
       {  
        OVERLAPPED ovlCommPort = new OVERLAPPED();  
        WriteFile(hComm,WriteBytes,WriteBytes.Length,ref BytesWritten,ref ovlCommPort);  
       }  
       else   
       {  
        throw(new ApplicationException("Comm Port Not Open"));  
       }    
       return BytesWritten;  
      }  
     }  
    }