C# 串口通信實例代碼


原文載自:https://www.cnblogs.com/shuaiheng/p/7443992.html

主要用於學習記錄

下面圖片是利用窗口控件所設計的界面。主要就是了解一下串口通信的機制。主要能夠實現發送數據和接收數據的功能。控件不熟悉的就去網上查找和學習。

下面是源代碼:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;

namespace SerialPortTest
{
  public partial class Form1 : Form
  {
    public Form1()
    {
      InitializeComponent();
    }

    SerialPort sp1 = new SerialPort();        //這個是定義的全局變量;
    private void Form1_Load(object sender, EventArgs e)        //窗體加載
    {          
      string[] str = SerialPort.GetPortNames();//檢查是否含有串口 
      if (str == null)
      {
        MessageBox.Show("本機沒有串口!", "Error");
        return;
      }

      foreach (string s in System.IO.Ports.SerialPort.GetPortNames())   //添加串口
      { 
        cbSerial.Items.Add(s);          //獲取有多少個COM口,添加到控件里
      }
      cbBaudRate.Items.Add("9600"); //對波特率,數據位,停止偉這幾個控件里面的值進行初始化顯示 這樣就可以避免我們調試時反復的對他們進行輸入
      cbDataBits.Items.Add("8");
      cbStop.Items.Add("1");
      cbParity.Items.Add("無");     

      cbSerial.SelectedIndex = 0; //獲取或是指當前選定項的索引//串口設置默認選擇項 
      cbBaudRate.SelectedIndex = 0;
      cbDataBits.SelectedIndex = 0;
      cbStop.SelectedIndex = 0;
      cbParity.SelectedIndex = 0;
      radio1.Checked = true;    //發送數據的“16進制”單選按鈕 
      rbRcvStr.Checked = true;

      Control.CheckForIllegalCrossThreadCalls = false;
      sp1.DataReceived += new SerialDataReceivedEventHandler(sp1_DataReceived); //訂閱委托  
    }

    private void btnSwitch_Click(object sender, EventArgs e)
    {
      //SerialPort sp1 = new SerialPort();
      if (!sp1.IsOpen)
      {
        try
        {
          string serialName = cbSerial.SelectedItem.ToString();//設置串口號 
          sp1.PortName = serialName;

          //設置各“串口設置”  
          string strBaudRate = cbBaudRate.Text;
          string strDateBits = cbDataBits.Text;
          string strStopBits = cbStop.Text;
          Int32 iBaudRate = Convert.ToInt32(strBaudRate);
          Int32 iDateBits = Convert.ToInt32(strDateBits);

          sp1.BaudRate = iBaudRate; //波特率  
          sp1.DataBits = iDateBits; //數據位  
          switch (cbStop.Text) //停止位  
          {
            case "1":
            sp1.StopBits = StopBits.One;
            break;
            case "1.5":  
            sp1.StopBits = StopBits.OnePointFive;
            break;
            case "2":
            sp1.StopBits = StopBits.Two;
            break;
            default:
            MessageBox.Show("Error:參數不正確!", "Error");
            break;
          }
          switch (cbParity.Text) //校驗位  
          {
            case "無":
            sp1.Parity = Parity.None;
            break;
            case "奇校驗":
            sp1.Parity = Parity.Odd;
            break;
            case "偶校驗":
            sp1.Parity = Parity.Even;
            break;
            default:
            MessageBox.Show("Error:參數不正確!", "Error");
            break;
          }

          if (sp1.IsOpen == true)//如果打開狀態,則先關閉一下  
          {
            sp1.Close();
          }
          //狀態欄設置  
          tsSpNum.Text = "串口號:" + sp1.PortName + "|";
          tsBaudRate.Text = "波特率:" + sp1.BaudRate + "|";
          tsDataBits.Text = "數據位:" + sp1.DataBits + "|";
          tsStopBits.Text = "停止位:" + sp1.StopBits + "|";
          tsParity.Text = "校驗位:" + sp1.Parity + "|";

          //設置必要控件不可用  
          cbSerial.Enabled = false;
          cbBaudRate.Enabled = false;
          cbDataBits.Enabled = false;
          cbStop.Enabled = false;
          cbParity.Enabled = false;

          sp1.Open(); //打開串口  
          btnSwitch.Text = "關閉串口";
          }
          catch (System.Exception ex)
          {
             MessageBox.Show("Error:" + ex.Message, "Error");
             return;
          }
      }
      else
      {
        //狀態欄設置  
        tsSpNum.Text = "串口號:未指定|";
        tsBaudRate.Text = "波特率:未指定|";
        tsDataBits.Text = "數據位:未指定|";
        tsStopBits.Text = "停止位:未指定|";
        tsParity.Text = "校驗位:未指定|"; 


        //恢復控件功能  
        //設置必要控件不可用  
        cbSerial.Enabled = true;
        cbBaudRate.Enabled = true;
        cbDataBits.Enabled = true;
        cbStop.Enabled = true;
        cbParity.Enabled = true;

        sp1.Close(); //關閉串口  
        btnSwitch.Text = "打開串口";
      }  
    }

    private void btnSend_Click(object sender, EventArgs e) //等待修改
    {
      if (!sp1.IsOpen) //如果沒打開  
      {  
        MessageBox.Show("請先打開串口!", "Error");  
        return;  
      }    

      String strSend = txtSend.Text;  
      if (radio1.Checked == true) //“16進制發送” 按鈕  
      {  
        //處理數字轉換,目的是將輸入的字符按空格、“,”等分組,以便發送數據時的方便(此處轉的比較麻煩,有高見者,請指點!)  
        string sendBuf = strSend;  
        string sendnoNull = sendBuf.Trim();  
        string sendNOComma = sendnoNull.Replace(',', ' '); //去掉英文逗號  
        string sendNOComma1 = sendNOComma.Replace(',', ' '); //去掉中文逗號  
        string strSendNoComma2 = sendNOComma1.Replace("0x", ""); //去掉0x  
        strSendNoComma2.Replace("0X", ""); //去掉0X  
        string[] strArray = strSendNoComma2.Split(' ');  
        int byteBufferLength = strArray.Length;  
        for (int i = 0; i <strArray.Length;i++)
        {
          if (strArray[i]=="")  
          {    
            byteBufferLength--;  
          }  
        }  

        byte[] byteBuffer = new byte[byteBufferLength];  
        int ii = 0;
        for (int i = 0; i < strArray.Length; i++) //對獲取的字符做相加運算  
        {
          Byte[] bytesOfStr = Encoding.Default.GetBytes(strArray[i]); 
          int decNum = 0;  
          if (strArray[i] == "")  
          {    
            continue;      
          }          
          else  
          {  
            decNum = Convert.ToInt32(strArray[i], 16); //strArray[i] == 12時,temp == 18  
          }  
          try //防止輸錯,使其只能輸入一個字節的字符,即只能在txtSend里輸入 “eb 90”等字符串,不能輸入“123 2345”等超出字節范圍的數字  
          {  
            byteBuffer[ii] = Convert.ToByte(decNum);  
          }  
          catch (System.Exception ex)  
          {  
            MessageBox.Show("字節越界,請逐個字節輸入!", "Error");  
            return;  
          }
        ii++;
      }
      sp1.Write(byteBuffer, 0, byteBuffer.Length);
      }
      else //以字符串形式發送時  
      {
        sp1.WriteLine(txtSend.Text); //寫入數據  
      }  
    }
    void sp1_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
      if (sp1.IsOpen) //嚴謹性
      {  
        byte[] byteRead = new byte[sp1.BytesToRead]; //BytesToRead:sp1接收的字符個數  
        if (radio2.Checked) //'發送字符串'單選按鈕  
        {  
          txtRcv.Text += sp1.ReadLine() + "\r\n"; //注意:回車換行必須這樣寫,單獨使用"\r"和"\n"都不會有效果  
          sp1.DiscardInBuffer(); //清空SerialPort控件的Buffer  
        }  
        else //'發送16進制按鈕'  
        {  
          try  
          {  
            Byte[] receivedData = new Byte[sp1.BytesToRead]; //創建接收字節數組  
            sp1.Read(receivedData, 0, receivedData.Length); //讀取數據  
            sp1.DiscardInBuffer(); //清空SerialPort控件的Buffer  
            string strRcv = null;  
            for (int i = 0; i < receivedData.Length; i++) //窗體顯示  
            {

              strRcv += receivedData[i].ToString("X2"); //16進制顯示  
            }
            txtRcv.Text += strRcv + "\r\n";
          }
          catch (System.Exception ex)
          {
            MessageBox.Show(ex.Message, "出錯提示");
            txtSend.Text = "";
          }
        }
      }
      else
      {
        MessageBox.Show("請打開某個串口", "錯誤提示");
      }
      DateTime dt = DateTime.Now;
      //txtRcv.Text += dt.GetDateTimeFormats('f')[0].ToString() + "\r\n";
      //txtRcv.SelectAll();
      //txtRcv.SelectionColor = Color.Blue; //改變字體的顏色  
    }

    private void btnClear_Click(object sender, EventArgs e)
    {
      //comboBox1.Items.Clear();  
      txtRcv.Clear();
      // foreach (Control ctrl in Controls)//或為groupBox1.Controls/panel1.Controls 可以做判斷
      //{
        // if (ctrl is TextBox)
        // ctrl.Text = "";
      //}
    }

    private void btnExit_Click(object sender, EventArgs e)
    {
      Application.Exit();
    }
  }
}  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM