在C#中實現串口通信的方法

jopen 9年前發布 | 3K 次閱讀 C#

    通常,在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();  

由于篇幅,以及串口通信涉及內容廣泛,我在這里只講這些。  

在上面我們已經把終端短信所需的各種原始技術有所了解,是可以小試牛刀的時候了。  </pre> 

    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;  
  }  
 }  
}  </pre> 


 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!