C#通信串口类

以前做过一段时间短信研究,找到一牛人写串口类,调试链接COM接口是成功的。

 

代码
  1 using System;
  2 using System.Runtime.InteropServices;
  3 
  4 namespace OPE
  5 {
  6     public class JustinIO
  7     {
  8         public class CommPort 
  9         {
 10 
 11             public string PortNum; 
 12             public int BaudRate;
 13             public byte ByteSize;
 14             public byte Parity; // 0-4=no,odd,even,mark,space 
 15             public byte StopBits; // 0,1,2 = 1, 1.5, 2 
 16             public int ReadTimeout;
 17             public string CenterNumber; 
 18   
 19             //comm port win32 file handle
 20             private int hComm = -1;
 21   
 22             public bool Opened = false;
 23    
 24             //win32 api constants
 25             private const uint GENERIC_READ = 0x80000000;
 26             private const uint GENERIC_WRITE = 0x40000000;
 27             private const int OPEN_EXISTING = 3;  
 28             private const int INVALID_HANDLE_VALUE = -1;
 29   
 30             [StructLayout(LayoutKind.Sequential)]
 31                 public struct DCB 
 32             {
 33                 //taken from c struct in platform sdk 
 34                 public int DCBlength;           // sizeof(DCB) 
 35                 public int BaudRate;            // 指定当前波特率 current baud rate
 36                 // these are the c struct bit fields, bit twiddle flag to set
 37                 public int fBinary;          // 指定是否允许二进制模式,在windows95中必须主TRUE binary mode, no EOF check 
 38                 public int fParity;          // 指定是否允许奇偶校验 enable parity checking 
 39                 public int fOutxCtsFlow;      // 指定CTS是否用于检测发送控制,当为TRUE是CTS为OFF,发送将被挂起。 CTS output flow control 
 40                 public int fOutxDsrFlow;      // 指定CTS是否用于检测发送控制 DSR output flow control 
 41                 public int fDtrControl;       // DTR_CONTROL_DISABLE值将DTR置为OFF, DTR_CONTROL_ENABLE值将DTR置为ON, DTR_CONTROL_HANDSHAKE允许DTR"握手" DTR flow control type 
 42                 public int fDsrSensitivity;   // 当该值为TRUE时DSR为OFF时接收的字节被忽略 DSR sensitivity 
 43                 public int fTXContinueOnXoff; // 指定当接收缓冲区已满,并且驱动程序已经发送出XoffChar字符时发送是否停止。TRUE时,在接收缓冲区接收到缓冲区已满的字节XoffLim且驱动程序已经发送出XoffChar字符中止接收字节之后,发送继续进行。 FALSE时,在接收缓冲区接收到代表缓冲区已空的字节XonChar且驱动程序已经发送出恢复发送的XonChar之后,发送继续进行。XOFF continues Tx 
 44                 public int fOutX;          // TRUE时,接收到XoffChar之后便停止发送接收到XonChar之后将重新开始 XON/XOFF out flow control 
 45                 public int fInX;           // TRUE时,接收缓冲区接收到代表缓冲区满的XoffLim之后,XoffChar发送出去接收缓冲区接收到代表缓冲区空的XonLim之后,XonChar发送出去 XON/XOFF in flow control 
 46                 public int fErrorChar;     // 该值为TRUE且fParity为TRUE时,用ErrorChar 成员指定的字符代替奇偶校验错误的接收字符 enable error replacement 
 47                 public int fNull;          // eTRUE时,接收时去掉空(0值)字节 enable null stripping 
 48                 public int fRtsControl;     // RTS flow control 
 49                 /*RTS_CONTROL_DISABLE时,RTS置为OFF
 50                  RTS_CONTROL_ENABLE时, RTS置为ON
 51                  RTS_CONTROL_HANDSHAKE时,
 52                  当接收缓冲区小于半满时RTS为ON
 53                   当接收缓冲区超过四分之三满时RTS为OFF
 54                  RTS_CONTROL_TOGGLE时,
 55                  当接收缓冲区仍有剩余字节时RTS为ON ,否则缺省为OFF*/
 56 
 57                 public int fAbortOnError;   // TRUE时,有错误发生时中止读和写操作 abort on error 
 58                 public int fDummy2;        // 未使用 reserved 
 59    
 60                 public uint flags;
 61                 public ushort wReserved;          // 未使用,必须为0 not currently used 
 62                 public ushort XonLim;             // 指定在XON字符发送这前接收缓冲区中可允许的最小字节数 transmit XON threshold 
 63                 public ushort XoffLim;            // 指定在XOFF字符发送这前接收缓冲区中可允许的最小字节数 transmit XOFF threshold 
 64                 public byte ByteSize;           // 指定端口当前使用的数据位 number of bits/byte, 4-8 
 65                 public byte Parity;             // 指定端口当前使用的奇偶校验方法,可能为:EVENPARITY,MARKPARITY,NOPARITY,ODDPARITY  0-4=no,odd,even,mark,space 
 66                 public byte StopBits;           // 指定端口当前使用的停止位数,可能为:ONESTOPBIT,ONE5STOPBITS,TWOSTOPBITS  0,1,2 = 1, 1.5, 2 
 67                 public char XonChar;            // 指定用于发送和接收字符XON的值 Tx and Rx XON character 
 68                 public char XoffChar;           // 指定用于发送和接收字符XOFF值 Tx and Rx XOFF character 
 69                 public char ErrorChar;          // 本字符用来代替接收到的奇偶校验发生错误时的值 error replacement character 
 70                 public char EofChar;            // 当没有使用二进制模式时,本字符可用来指示数据的结束 end of input character 
 71                 public char EvtChar;            // 当接收到此字符时,会产生一个事件 received event character 
 72                 public ushort wReserved1;         // 未使用 reserved; do not use 
 73             }
 74 
 75             [StructLayout(LayoutKind.Sequential)]
 76                 private struct COMMTIMEOUTS 
 77             {  
 78                 public int ReadIntervalTimeout; 
 79                 public int ReadTotalTimeoutMultiplier; 
 80                 public int ReadTotalTimeoutConstant; 
 81                 public int WriteTotalTimeoutMultiplier; 
 82                 public int WriteTotalTimeoutConstant; 
 83             }  
 84 
 85             [StructLayout(LayoutKind.Sequential)] 
 86                 private struct OVERLAPPED 
 87             { 
 88                 public int  Internal; 
 89                 public int  InternalHigh; 
 90                 public int  Offset; 
 91                 public int  OffsetHigh; 
 92                 public int hEvent; 
 93             }  
 94   
 95             [DllImport("kernel32.dll")]
 96             private static extern int CreateFile(
 97                 string lpFileName,                         // 要打开的串口名称
 98                 uint dwDesiredAccess,                      // 指定串口的访问方式,一般设置为可读可写方式
 99                 int dwShareMode,                          // 指定串口的共享模式,串口不能共享,所以设置为0
100                 int lpSecurityAttributes, // 设置串口的安全属性,WIN9X下不支持,应设为NULL
101                 int dwCreationDisposition,                // 对于串口通信,创建方式只能为OPEN_EXISTING
102                 int dwFlagsAndAttributes,                 // 指定串口属性与标志,设置为FILE_FLAG_OVERLAPPED(重叠I/O操作),指定串口以异步方式通信
103                 int hTemplateFile                        // 对于串口通信必须设置为NULL
104                 );
105             [DllImport("kernel32.dll")]
106             private static extern bool GetCommState(
107                 int hFile,  //通信设备句柄
108                 ref DCB lpDCB    // 设备控制块DCB
109                 ); 
110             [DllImport("kernel32.dll")]
111             private static extern bool BuildCommDCB(
112                 string lpDef,  // 设备控制字符串
113                 ref DCB lpDCB     // 设备控制块
114                 );
115             [DllImport("kernel32.dll")]
116             private static extern bool SetCommState(
117                 int hFile,  // 通信设备句柄
118                 ref DCB lpDCB    // 设备控制块
119                 );
120             [DllImport("kernel32.dll")]
121             private static extern bool GetCommTimeouts(
122                 int hFile,                  // 通信设备句柄 handle to comm device
123                 ref COMMTIMEOUTS lpCommTimeouts  // 超时时间 time-out values
124                 ); 
125             [DllImport("kernel32.dll")] 
126             private static extern bool SetCommTimeouts(
127                 int hFile,                  // 通信设备句柄 handle to comm device
128                 ref COMMTIMEOUTS lpCommTimeouts  // 超时时间 time-out values
129                 );
130             [DllImport("kernel32.dll")]
131             private static extern bool ReadFile(
132                 int hFile,                // 通信设备句柄 handle to file
133                 byte[] lpBuffer,             // 数据缓冲区 data buffer
134                 int nNumberOfBytesToRead,  // 多少字节等待读取 number of bytes to read
135                 ref int lpNumberOfBytesRead, // 读取多少字节 number of bytes read
136                 ref OVERLAPPED lpOverlapped    // 溢出缓冲区 overlapped buffer
137                 );
138             [DllImport("kernel32.dll")] 
139             private static extern bool WriteFile(
140                 int hFile,                    // 通信设备句柄 handle to file
141                 byte[] lpBuffer,                // 数据缓冲区 data buffer
142                 int nNumberOfBytesToWrite,     // 多少字节等待写入 number of bytes to write
143                 ref int lpNumberOfBytesWritten,  // 已经写入多少字节 number of bytes written
144                 ref OVERLAPPED lpOverlapped        // 溢出缓冲区 overlapped buffer
145                 );
146             [DllImport("kernel32.dll")]
147             private static extern bool CloseHandle(
148                 int hObject   // handle to object
149                 );
150             [DllImport("kernel32.dll")]
151             private static extern uint GetLastError();
152   
153             public void Open()
154             {
155   
156                 DCB dcbCommPort = new DCB();
157                 COMMTIMEOUTS ctoCommPort = new COMMTIMEOUTS(); 
158      
159                 // 打开串口 OPEN THE COMM PORT.
160                 hComm = CreateFile(PortNum ,GENERIC_READ | GENERIC_WRITE,00,OPEN_EXISTING,0,0);
161                 // 如果串口没有打开,就打开 IF THE PORT CANNOT BE OPENED, BAIL OUT.
162                 if(hComm == INVALID_HANDLE_VALUE) 
163                 {
164                     throw(new ApplicationException("非法操作,不能打开串口!"));
165                 }
166   
167                 // 设置通信超时时间 SET THE COMM TIMEOUTS.
168                 GetCommTimeouts(hComm,ref ctoCommPort);
169                 ctoCommPort.ReadTotalTimeoutConstant = ReadTimeout;
170                 ctoCommPort.ReadTotalTimeoutMultiplier = 0;
171                 ctoCommPort.WriteTotalTimeoutMultiplier = 0;
172                 ctoCommPort.WriteTotalTimeoutConstant = 0;  
173                 SetCommTimeouts(hComm,ref ctoCommPort);
174   
175                 // 设置串口 SET BAUD RATE, PARITY, WORD SIZE, AND STOP BITS.
176                 GetCommState(hComm, ref dcbCommPort);
177                 dcbCommPort.BaudRate=BaudRate;
178                 dcbCommPort.flags=0;
179                 //dcb.fBinary=1;
180                 dcbCommPort.flags|=1;
181                 if (Parity>0)
182                 {
183                     //dcb.fParity=1
184                     dcbCommPort.flags|=2;
185                 }
186                 dcbCommPort.Parity=Parity;
187                 dcbCommPort.ByteSize=ByteSize;
188                 dcbCommPort.StopBits=StopBits;
189                 //if (!BuildCommDCB("9600,n,8,1  ", ref  dcbCommPort))
190                 //{
191                 //    throw (new ApplicationException("非法操作,不能打开串口!  "));
192                 //}  
193 
194                 if (!SetCommState(hComm, ref dcbCommPort))
195                 {
196                     //uint ErrorNum=GetLastError();
197                     throw(new ApplicationException("非法操作,不能打开串口!"));
198                 }
199                 //unremark to see if setting took correctly
200                 //DCB dcbCommPort2 = new DCB();
201                 //GetCommState(hComm, ref dcbCommPort2);
202                 Opened = true;
203             }
204   
205             public void Close() 
206             {
207                 if (hComm!=INVALID_HANDLE_VALUE) 
208                 {
209                     CloseHandle(hComm);
210                 }
211             }
212   
213             public byte[] Read(int NumBytes) 
214             {
215                 byte[] BufBytes;
216                 byte[] OutBytes;
217                 BufBytes = new byte[NumBytes];
218                 if (hComm!=INVALID_HANDLE_VALUE) 
219                 {
220                     OVERLAPPED ovlCommPort = new OVERLAPPED();
221                     int BytesRead=0;
222                     ReadFile(hComm,BufBytes,NumBytes,ref BytesRead,ref ovlCommPort);
223                     OutBytes = new byte[BytesRead];
224                     Array.Copy(BufBytes,OutBytes,BytesRead);
225                 } 
226                 else 
227                 {
228                     throw(new ApplicationException("串口未打开!"));
229                 }
230                 return OutBytes;
231             }
232   
233             public void Write(byte[] WriteBytes) 
234             {
235                 if (hComm!=INVALID_HANDLE_VALUE) 
236                 {
237                     OVERLAPPED ovlCommPort = new OVERLAPPED();
238                     int BytesWritten = 0;
239                     WriteFile(hComm,WriteBytes,WriteBytes.Length,ref BytesWritten,ref ovlCommPort);
240                 }
241                 else 
242                 {
243                     throw(new ApplicationException("串口未打开!"));
244                 }  
245             }
246         }
247 
248         public class HexCon 
249         {
250             // 把十六进制字符串转换成字节型和把字节型转换成十六进制字符串 converter hex string to byte and byte to hex string
251             public static string ByteToString(byte[] InBytes) 
252             {
253                 string StringOut="";
254                 foreach (byte InByte in InBytes) 
255                 {
256                     StringOut=StringOut + String.Format("{0:X2} ",InByte);
257                 }
258                 return StringOut; 
259             }
260             public static byte[] StringToByte(string InString) 
261             {
262                 string[] ByteStrings;
263                 ByteStrings = InString.Split(" ".ToCharArray());
264                 byte[] ByteOut;
265                 ByteOut = new byte[ByteStrings.Length-1];
266                 for (int i = 0;i==ByteStrings.Length-1;i++
267                 {
268                     ByteOut[i] = Convert.ToByte(("0x" + ByteStrings[i]));
269                 } 
270                 return ByteOut;
271             }
272         }
273     } 
274 }
275 
276 

 

 

posted @ 2009-12-04 10:08  老呆  阅读(3478)  评论(0编辑  收藏  举报