Home  >  Article  >  Backend Development  >  How to implement serial port communication in C#

How to implement serial port communication in C#

大家讲道理
大家讲道理Original
2016-11-10 10:20:591871browse

Usually, we have four methods to implement serial port communication in C#:
First: Through the MSCOMM control, this is the simplest and most convenient method. However, it is difficult to control the function freely. At the same time, this control is not included in the system itself, so it needs to be registered, which is beyond the scope of this article. You can visit http://www.devhood.com/tutorials/tutorial_details.aspx?tutorial_id=320, a tutorial written by a foreign netizen. The author is very enthusiastic. I once sent him an email and he responded quickly.

Second: Microsoft has launched a new serial port control in .NET, which is implemented based on .NET's P/Invoke calling method. For details, you can visit the Microsoft website http://msdn.microsoft.com/msdnmag/issues/02/ 10/NETSerialComm/default.aspx for easy access to more information.

Third: Just use third-party controls, but generally you have to pay, which is not practical and will not be considered.

Fourth: Use API to write serial port communication yourself, which is more difficult, but for us, it can It is convenient to realize the various functions you want

In this article, we use the fourth method to realize serial communication, but instead of writing it ourselves, we use a ready-made packaged class library from foreign netizens, but the function is simpler than ours That's enough.

During the entire terminal text message operation, only four functions are used to communicate with the serial port, namely opening, writing, reading, and closing the serial port. The following is the definition of the four functions of the class library:

Open the serial port:

Function prototype: public void Open()

Description: Open the preset port

Example:

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

Write the serial port :

Function prototype: public void Write(byte[] WriteBytes)

WriteBytes is the bytes you write. Note that the string must be converted into a byte array for communication

Example:

ss_port.Write(Encoding.ASCII.GetBytes("AT+CGMIr")); //Get the mobile phone brand

Read serial port:

Function prototype: public byte[] Read(int NumBytes)

NumBytes Read the cache number. Note that what is read is a byte array. In actual applications, character conversion is required

Example:

string response = Encoding.ASCII.GetString(ss_port.Read (128)); //Read 128 bytes buffer

Close the serial port:

Function prototype: ss_port.Close()

Example:

ss_port.Close();

Due to the length and the extensive content involved in serial communication, I will only talk about these here.

We have already understood the various primitive technologies required for terminal text messaging, and it’s time to try it out.

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


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Previous article:C# file merging codeNext article:C# file merging code