C# 串口通信總結

我們知道對於 
 
  標準DLL,可以採用DllImport進行調用。例如:

 

 [DllImport( " KMY350X.dll ")]
         private  static  extern  int OpenPort( int PortNum,  int BaudRate);

 

如果一些廠家比較懶的話,沒有提供相應的dll,我們只能對它進行串口通信編程了。以前從沒接觸過串口編程,最近在一個項目中有幾個地方都需要採用串口通信,跟公司一個老手請教後,感覺學到了很多東西,特在此做個總結:

     

     一:首先我們來認識下什麼是串口:

 

右鍵 我的電腦-管理-設備管理器-端口,選擇一個端口,點擊屬性。

        

 

我們可以看到該串口的屬性,在C#中我們使用SerialPort類來表示串口

 

複製代碼
            ConfigClass config =  new ConfigClass();
    comm.serialPort.PortName = config.ReadConfig( " SendHealCard ");
             // 波特率
            comm.serialPort.BaudRate =  9600;
             // 數據位
            comm.serialPort.DataBits =  8;
             // 兩個停止位
            comm.serialPort.StopBits = System.IO.Ports.StopBits.One;
             // 無奇偶校驗位
            comm.serialPort.Parity = System.IO.Ports.Parity.None;
            comm.serialPort.ReadTimeout =  100;
            comm.serialPort.WriteTimeout = - 1;
複製代碼

 

        二:串口調試工具:

在對串口進行編程時候,我們要向串口發送指令,然後我們解析串口返回的指令。在這裏向大家推薦一款工具。

        串口調試助手.exe

        

         

 

將要發送的指令用空格隔開,選擇HEX顯示爲放回的字符串。

       

三:正式編程:

       

編寫Comm類:

複製代碼
     public class Comm   
     {
         public  delegate  void EventHandle( byte[] readBuffer);
         public  event EventHandle DataReceived;

         public SerialPort serialPort;
        Thread thread;
         volatile  bool _keepReading;

         public Comm()
        {
            serialPort =  new SerialPort();
            thread =  null;
            _keepReading =  false;
        }

         public  bool IsOpen
        {
             get 
            {
                 return serialPort.IsOpen;
            }
        }        

         private  void StartReading()
        {
             if (!_keepReading)
            {
                _keepReading =  true;
                thread =  new Thread( new ThreadStart(ReadPort));
                thread.Start();
            }
        }

         private  void StopReading()
        {
             if (_keepReading)
            {
                _keepReading =  false;
                thread.Join();
                thread =  null;                
            }
        }

         private  void ReadPort()
        {
             while (_keepReading)
            {
                 if (serialPort.IsOpen)
                {
                     int count = serialPort.BytesToRead;
                     if (count >  0)
                    {
                         byte[] readBuffer =  new  byte[count];
                         try
                        {
                            Application.DoEvents();
                            serialPort.Read(readBuffer,  0, count);
                             if(DataReceived !=  null)
                                DataReceived(readBuffer);
                            Thread.Sleep( 100);
                        }
                         catch (TimeoutException)
                        {
                        }
                    }
                }
            }
        }

         public  void Open()
        {
            Close();            
            serialPort.Open();
             if (serialPort.IsOpen)
            {
                StartReading();
            }
             else
            {
                MessageBox.Show( " 串口打開失敗! ");
            }
        }

         public  void Close()
        {
            StopReading();
            serialPort.Close();
        }

         public  void WritePort( byte[] send,  int offSet,  int count)
        {
             if (IsOpen)
            {
                serialPort.Write(send, offSet, count);
            }
        }
    }
複製代碼

   

註冊串口:

     

複製代碼
            Comm 
 
   comm = new Comm();
            ConfigClass config =  new ConfigClass();
            comm.serialPort.PortName = config.ReadConfig( " SendHealCard ");
             // 波特率
            comm.serialPort.BaudRate =  9600;
             // 數據位
            comm.serialPort.DataBits =  8;
             // 兩個停止位
            comm.serialPort.StopBits = System.IO.Ports.StopBits.One;
             // 無奇偶校驗位
            comm.serialPort.Parity = System.IO.Ports.Parity.None;
            comm.serialPort.ReadTimeout =  100;
     comm.serialPort.WriteTimeout = -1; 
     
      
comm.Open();
            if (comm.IsOpen)
            {
                comm.DataReceived += new Comm.EventHandle(comm_DataReceived);
            }
複製代碼

 

發送指令:

      

複製代碼
         ///   <summary>
///  髮卡到機口
        
///   </summary>
         private  void SendCardToOut()
        {
            is_read_card =  false;
            sendCardToOut =  true;
             byte[] send = {  0x020x460x430x340x030x30 };
             if (comm.IsOpen)
            {
                comm.WritePort(send,  0, send.Length);
            }
        } 
複製代碼

 

收到指令,並解析:

     

複製代碼
        
 
    void comm_DataReceived(byte[] readBuffer1)
 {
             // log.Info(HexCon.ByteToString(readBuffer));
             if (readBuffer1.Length ==  1)
            {
                receive = HealCardClass.ByteToString(readBuffer1);
                 string str =  " 06 ";
                 if ( string.Equals(receive.Trim(), str, StringComparison.CurrentCultureIgnoreCase))
                {
                     try
                    {
                         if (is_read_card)
                        {
                             byte[] send =  new  byte[ 1];
                            send[ 0] =  0x05;
                            comm.WritePort(send,  0, send.Length);
                            Thread.Sleep( 500);
                            comm.DataReceived -=  new Comm.EventHandle(comm_DataReceived);
                            InitReadComm();
                        }
                         if (sendCardToOut)
                        {
                             byte[] send =  new  byte[ 1];
                            send[ 0] =  0x05;
                            comm.WritePort(send,  0, send.Length);


                            readComm.DataReceived -=  new Comm.EventHandle(readComm_DataReceived);
                            readComm.Close();

                            log.Info( " 髮卡完成! ");
                            lblMsg.Text =  " 髮卡成功! ";
                            lblSendCardMsg.Text =  " 髮卡完成,請收好卡! ";
                            timer1.Tick -=  new EventHandler(timer1_Tick);
                            PlaySound();
                             this.btnOK.Enabled =  true;


                        }
                    }
                     catch (Exception ex)
                    {
                        log.Info(ex.ToString());
                    }
                }
            }
  } 
複製代碼

 

至此,串口通信編程告一段落