1. 程式人生 > >串列埠通訊類JustinIO.CommPort及使用方法

串列埠通訊類JustinIO.CommPort及使用方法

  1. using System;
  2. using System.Runtime.InteropServices;
  3. using System.Text;
  4. namespace JustinIO
  5. {
  6. publicclass CommPort
  7.     {
  8. publicstring PortName;
  9. publicint BaudRate;
  10. publicbyte DataBits;
  11. publicbyte Parity; // 0-4=no,odd,even,mark,space 
  12. publicbyte StopBits; // 0,1,2 = 1, 1.5, 2 
  13. publicint ReadTimeout;
  14. //comm port win32 file handle
  15. privateint hComm = -1;
  16. publicbool Opened = false;
  17. publicbool IsOpen = false;
  18. //win32 api constants
  19. privateconstuint GENERIC_READ = 0x80000000;
  20. privateconstuint GENERIC_WRITE = 0x40000000;
  21. privateconstint OPEN_EXISTING = 3;
  22. privateconstint INVALID_HANDLE_VALUE = -1;
  23.         [StructLayout(LayoutKind.Sequential)]
  24. publicstruct DCB
  25.         {
  26. //taken from c struct in platform sdk 
  27. publicint DCBlength; // sizeof(DCB) 
  28. publicint BaudRate; // 指定當前波特率 current baud rate
  29. // these are the c struct bit fields, bit twiddle flag to set
  30. publicint fBinary; // 指定是否允許二進位制模式,在windows95中必須主TRUE binary mode, no EOF check 
  31. public
    int fParity; // 指定是否允許奇偶校驗 enable parity checking 
  32. publicint fOutxCtsFlow; // 指定CTS是否用於檢測傳送控制,當為TRUE是CTS為OFF,傳送將被掛起。 CTS output flow control 
  33. publicint fOutxDsrFlow; // 指定CTS是否用於檢測傳送控制 DSR output flow control 
  34. publicint fDtrControl; // DTR_CONTROL_DISABLE值將DTR置為OFF, DTR_CONTROL_ENABLE值將DTR置為ON, DTR_CONTROL_HANDSHAKE允許DTR"握手" DTR flow control type 
  35. publicint fDsrSensitivity; // 當該值為TRUE時DSR為OFF時接收的位元組被忽略 DSR sensitivity 
  36. publicint fTXContinueOnXoff; // 指定當接收緩衝區已滿,並且驅動程式已經發送出XoffChar字元時傳送是否停止。TRUE時,在接收緩衝區接收到緩衝區已滿的位元組XoffLim且驅動程式已經發送出XoffChar字元中止接收位元組之後,傳送繼續進行。 FALSE時,在接收緩衝區接收到代表緩衝區已空的位元組XonChar且驅動程式已經發送出恢復傳送的XonChar之後,傳送繼續進行。XOFF continues Tx 
  37. publicint fOutX; // TRUE時,接收到XoffChar之後便停止傳送接收到XonChar之後將重新開始 XON/XOFF out flow control 
  38. publicint fInX; // TRUE時,接收緩衝區接收到代表緩衝區滿的XoffLim之後,XoffChar傳送出去接收緩衝區接收到代表緩衝區空的XonLim之後,XonChar傳送出去 XON/XOFF in flow control 
  39. publicint fErrorChar; // 該值為TRUE且fParity為TRUE時,用ErrorChar 成員指定的字元代替奇偶校驗錯誤的接收字元 enable error replacement 
  40. publicint fNull; // eTRUE時,接收時去掉空(0值)位元組 enable null stripping 
  41. publicint fRtsControl; // RTS flow control 
  42. /*RTS_CONTROL_DISABLE時,RTS置為OFF
  43.             RTS_CONTROL_ENABLE時, RTS置為ON
  44.             RTS_CONTROL_HANDSHAKE時,
  45.             當接收緩衝區小於半滿時RTS為ON
  46.             當接收緩衝區超過四分之三滿時RTS為OFF
  47.             RTS_CONTROL_TOGGLE時,
  48.             當接收緩衝區仍有剩餘位元組時RTS為ON ,否則預設為OFF*/
  49. publicint fAbortOnError; // TRUE時,有錯誤發生時中止讀和寫操作 abort on error 
  50. publicint fDummy2; // 未使用 reserved 
  51. publicuint flags;
  52. publicushort wReserved; // 未使用,必須為0 not currently used 
  53. publicushort XonLim; // 指定在XON字元傳送這前接收緩衝區中可允許的最小位元組數 transmit XON threshold 
  54. publicushort XoffLim; // 指定在XOFF字元傳送這前接收緩衝區中可允許的最小位元組數 transmit XOFF threshold 
  55. publicbyte ByteSize; // 指定埠當前使用的資料位 number of bits/byte, 4-8 
  56. publicbyte Parity; // 指定埠當前使用的奇偶校驗方法,可能為:EVENPARITY,MARKPARITY,NOPARITY,ODDPARITY 0-4=no,odd,even,mark,space 
  57. publicbyte StopBits; // 指定埠當前使用的停止位數,可能為:ONESTOPBIT,ONE5STOPBITS,TWOSTOPBITS 0,1,2 = 1, 1.5, 2 
  58. publicchar XonChar; // 指定用於傳送和接收字元XON的值 Tx and Rx XON character 
  59. publicchar XoffChar; // 指定用於傳送和接收字元XOFF值 Tx and Rx XOFF character 
  60. publicchar ErrorChar; // 本字元用來代替接收到的奇偶校驗發生錯誤時的值 error replacement character 
  61. publicchar EofChar; // 當沒有使用二進位制模式時,本字元可用來指示資料的結束 end of input character 
  62. publicchar EvtChar; // 當接收到此字元時,會產生一個事件 received event character 
  63. publicushort wReserved1; // 未使用 reserved; do not use 
  64.         }
  65.         [StructLayout(LayoutKind.Sequential)]
  66. privatestruct COMMTIMEOUTS
  67.         {
  68. publicint ReadIntervalTimeout;
  69. publicint ReadTotalTimeoutMultiplier;
  70. publicint ReadTotalTimeoutConstant;
  71. publicint WriteTotalTimeoutMultiplier;
  72. publicint WriteTotalTimeoutConstant;
  73.         }
  74.         [StructLayout(LayoutKind.Sequential)]
  75. privatestruct OVERLAPPED
  76.         {
  77. publicint Internal;
  78. publicint InternalHigh;
  79. publicint Offset;
  80. publicint OffsetHigh;
  81. publicint hEvent;
  82.         }
  83.         [DllImport("kernel32.dll")]
  84. privatestaticexternint CreateFile(
  85. string lpFileName, // 要開啟的串列埠名稱
  86. uint dwDesiredAccess, // 指定串列埠的訪問方式,一般設定為可讀可寫方式
  87. int dwShareMode, // 指定串列埠的共享模式,串列埠不能共享,所以設定為0
  88. int lpSecurityAttributes, // 設定串列埠的安全屬性,WIN9X下不支援,應設為NULL
  89. int dwCreationDisposition, // 對於串列埠通訊,建立方式只能為OPEN_EXISTING
  90. int dwFlagsAndAttributes, // 指定串列埠屬性與標誌,設定為FILE_FLAG_OVERLAPPED(重疊I/O操作),指定串列埠以非同步方式通訊
  91. int hTemplateFile // 對於串列埠通訊必須設定為NULL
  92.         );
  93.         [DllImport("kernel32.dll")]
  94. privatestaticexternbool GetCommState(
  95. int hFile, //通訊裝置控制代碼
  96. ref DCB lpDCB // 裝置控制塊DCB
  97.         );
  98.         [DllImport("kernel32.dll")]
  99. privatestaticexternbool BuildCommDCB(
  100. string lpDef, // 裝置控制字串
  101. ref DCB lpDCB // 裝置控制塊
  102.         );
  103.         [DllImport("kernel32.dll")]
  104. privatestaticexternbool SetCommState(
  105. int hFile, // 通訊裝置控制代碼
  106. ref DCB lpDCB // 裝置控制塊
  107.         );
  108.         [DllImport("kernel32.dll")]
  109. privatestaticexternbool GetCommTimeouts(
  110. int hFile, // 通訊裝置控制代碼 handle to comm device
  111. ref COMMTIMEOUTS lpCommTimeouts // 超時時間 time-out values
  112.         );
  113.         [DllImport("kernel32.dll")]
  114. privatestaticexternbool SetCommTimeouts(
  115. int hFile, // 通訊裝置控制代碼 handle to comm device
  116. ref COMMTIMEOUTS lpCommTimeouts // 超時時間 time-out values
  117.         );
  118.         [DllImport("kernel32.dll")]
  119. privatestaticexternbool ReadFile(
  120. int hFile, // 通訊裝置控制代碼 handle to file
  121. byte[] lpBuffer, // 資料緩衝區 data buffer
  122. int nNumberOfBytesToRead, // 多少位元組等待讀取 number of bytes to read
  123. refint lpNumberOfBytesRead, // 讀取多少位元組 number of bytes read
  124. ref OVERLAPPED lpOverlapped // 溢位緩衝區 overlapped buffer
  125.         );
  126.         [DllImport("kernel32.dll")]
  127. privatestaticexternbool WriteFile(
  128. int hFile, // 通訊裝置控制代碼 handle to file
  129. byte[] lpBuffer, // 資料緩衝區 data buffer
  130. int nNumberOfBytesToWrite, // 多少位元組等待寫入 number of bytes to write
  131. refint lpNumberOfBytesWritten, // 已經寫入多少位元組 number of bytes written
  132. ref OVERLAPPED lpOverlapped // 溢位緩衝區 overlapped buffer
  133.         );
  134.         [DllImport("kernel32.dll")]
  135. privatestaticexternbool CloseHandle(
  136. int hObject // handle to object
  137.         );
  138.         [DllImport("kernel32.dll")]
  139. privatestaticexternuint GetLastError();
  140. publicvoid Open()
  141.         {
  142.             DCB dcbCommPort = new DCB();
  143.             COMMTIMEOUTS ctoCommPort = new COMMTIMEOUTS();
  144. // 開啟串列埠 OPEN THE COMM PORT.
  145. string num = PortName.Replace("COM""");
  146. if (int.Parse(num) >= 10)
  147.                 hComm = CreateFile("//./"" + PortName, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
  148. else
  149.                 hComm = CreateFile(PortName, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
  150. // 如果串列埠沒有開啟,就開啟 IF THE PORT CANNOT BE OPENED, BAIL OUT.
  151. if (hComm == INVALID_HANDLE_VALUE)
  152.             {
  153. throw (new Exception("非法操作,不能開啟串列埠!"));
  154.             }
  155. // 設定通訊超時時間 SET THE COMM TIMEOUTS.
  156.             GetCommTimeouts(hComm, ref ctoCommPort);
  157.             ctoCommPort.ReadTotalTimeoutConstant = ReadTimeout;
  158.             ctoCommPort.ReadTotalTimeoutMultiplier = 0;
  159.             ctoCommPort.WriteTotalTimeoutMultiplier = 0;
  160.             ctoCommPort.WriteTotalTimeoutConstant = 0;
  161.             SetCommTimeouts(hComm, ref ctoCommPort);
  162. // 設定串列埠 SET BAUD RATE, PARITY, WORD SIZE, AND STOP BITS.
  163.             GetCommState(hComm, ref dcbCommPort);
  164.             dcbCommPort.BaudRate = BaudRate;
  165.             dcbCommPort.flags = 0;
  166. //dcb.fBinary=1;
  167.             dcbCommPort.flags |= 1;
  168. if (Parity > 0)
  169.             {
  170. //dcb.fParity=1
  171.                 dcbCommPort.flags |= 2;
  172.             }
  173.             dcbCommPort.Parity = Parity;
  174.             dcbCommPort.ByteSize = DataBits;
  175.             dcbCommPort.StopBits = StopBits;
  176. if (!SetCommState(hComm, ref dcbCommPort))
  177.             {
  178. //uint ErrorNum=GetLastError();
  179. throw (new ApplicationException("非法操作,不能開啟串列埠!"));
  180.             }
  181. //unremark to see if setting took correctly
  182. //DCB dcbCommPort2 = new DCB();
  183. //GetCommState(hComm, ref dcbCommPort2);
  184.             Opened = true;
  185.             IsOpen = true;
  186.         }
  187. publicvoid Close()
  188.         {
  189. if (hComm != INVALID_HANDLE_VALUE)
  190.             {
  191.                 CloseHandle(hComm);
  192.             }
  193.         }
  194. publicbyte[] Read(int NumBytes)
  195.         {
  196. byte[] BufBytes;
  197. byte[] OutBytes;
  198.             BufBytes = newbyte[NumBytes];
  199. if (hComm != INVALID_HANDLE_VALUE)
  200.             {
  201.                 OVERLAPPED ovlCommPort = new OVERLAPPED();
  202. int BytesRead = 0;
  203.                 ReadFile(hComm, BufBytes, NumBytes, ref BytesRead, ref ovlCommPort);
  204.                 OutBytes = newbyte[BytesRead];
  205.                 Array.Copy(BufBytes, OutBytes, BytesRead);
  206.             }
  207. else
  208.             {
  209. throw (new ApplicationException("串列埠未開啟!"));
  210.             }
  211. return OutBytes;
  212.         }
  213. publicstring ReadExisting()
  214.         {
  215. return Encoding.ASCII.GetString(Read(128));
  216.         }
  217. publicvoid Write(byte[] WriteBytes)
  218.         {
  219. if (hComm != INVALID_HANDLE_VALUE)
  220.             {
  221.                 OVERLAPPED ovlCommPort = new OVERLAPPED();
  222. int BytesWritten = 0;
  223.                 WriteFile(hComm, WriteBytes, WriteBytes.Length, ref BytesWritten, ref ovlCommPort);
  224.             }
  225. else
  226.             {
  227. throw (new ApplicationException("串列埠未開啟!"));
  228.             }
  229.         }
  230. publicvoid Write(string WriteString, Encoding CoderType)
  231.         {
  232.             Write(CoderType.GetBytes(WriteString));
  233.         }
  234. publicvoid Write(string WriteString)
  235.         {
  236.             Write(Encoding.ASCII.GetBytes(WriteString));
  237.         }
  238.     }
  239. }

介紹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();