zoukankan      html  css  js  c++  java
  • C# 串口通信

    串口通信程序是很多需要了解的,作为一个新手,按照网上的教程编写成功了,所以准备写下来保存,也许也能帮到别人,觉得这是一件很有意义的事。言归正传,这是窗口应用程序,下面图片是利用窗口控件所设计的界面。主要就是了解一下串口通信的机制。主要能够实现发送数据和接收数据的功能。控件不熟悉的就去网上查找和学习。

    下面是源代码:

    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() + " "; //注意:回车换行必须这样写,单独使用" "和" "都不会有效果
              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 + " ";
              }
              catch (System.Exception ex)
              {
                MessageBox.Show(ex.Message, "出错提示");
                txtSend.Text = "";
              }
            }
          }
          else
          {
            MessageBox.Show("请打开某个串口", "错误提示");
          }
          DateTime dt = DateTime.Now;
          //txtRcv.Text += dt.GetDateTimeFormats('f')[0].ToString() + " ";
          //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();
        }
      }
    }  

  • 相关阅读:
    [备忘录]Download Google Drive Files using wget
    RangeNet++ spheracal projection的理解
    k8s容器的命名规则
    5分钟让你知道什么是PKI
    Kubernetes 学习15 kubernetes 认证及serviceaccount
    Kubernetes 学习10 Service资源
    SQL优化技巧
    一文看懂 MySQL 高性能优化技巧实践
    MySQL表的碎片整理和空间回收小结
    详谈 MySQL Online DDL
  • 原文地址:https://www.cnblogs.com/shuaiheng/p/7443992.html
Copyright © 2011-2022 走看看