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

大家讲道理
发布: 2016-11-10 10:20:59
原创
1919 人浏览过

通常,在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; 
  } 
 } 
}
登录后复制


来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
最新问题
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板