C#对串口数据接收、发送的处理

C# 同时被 2 个专栏收录
123 篇文章 2 订阅
38 篇文章 2 订阅

最近在做与设备进行串口通信交互的项目,然后简单记录一下过程

使用的winform应用程序

方式1

1.声明串口对象 或者直接在工具箱拖拽串口控件

本篇文章不采用拖拽工具箱控件 直接声明对象
声明串口对象

SerialPort port = new SerialPort();//在选择了串口之后设置 串口、波特率、校验位等

也可以直接拖拽工具箱的串口控件SerialPort
在这里插入图片描述

2.引用串口命名控件 声明串口对象、声明委托

using System.IO.Ports;

		SerialPort serialPort1 = new SerialPort();
        public delegate void Displaydelegate(byte[] InputBuf);
        public Displaydelegate disp_delegate;
        public Form1()
        {
            InitializeComponent();

            disp_delegate = new Displaydelegate(DispUI);
            serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
        }

3.先获取电脑所有串口列表

获取到列表后绑定给conboBox,以便选择串口打开 在load事件绑定下拉框

String[] portnames = SerialPort.GetPortNames();
            foreach (var item in portnames)
            {
                comboBox1.Items.Add(item);
            }

4.实例化串口打开串口

选择串口后实例化串口

string aaa = comboBox1.SelectedItem.ToString();
serialPort11 = new SerialPort(aaa, 9600, Parity.None, 8, StopBits.One); //初始化串口设置   serialPort11 声明为全局变量

            serialPort1.Open();
            if (serialPort1.IsOpen)
            {
                MessageBox.Show("打开成功");
            }
            else
            {
                MessageBox.Show("打开失败");
            }

5.写一个接收数据事件获取串口发送来的数据

 //编写一个接收事件
        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
           // writetxt("端口名称:" + serialPort1.PortName + "====" + "端口名称:" + "波特率:" + serialPort1.BaudRate + "串口状态:" + serialPort1.IsOpen + "错误信息:无");
            //string receive = "";//数据接收
            try
            {
                Thread.Sleep(100);  //(毫秒)等待一定时间,确保数据的完整性 int len        
                int len = serialPort1.BytesToRead;
                if (len != 0)
                {
                    byte[] buff = new byte[len];
                    serialPort1.Read(buff, 0, len);
                    //receive = Encoding.Default.GetString(buff);//数据接收内容
                    //textBox1.Text = receive + "\r\n"; //不能直接给textbox1 不然会报错
                    this.Invoke(disp_delegate, buff);
                }
            }
            catch (Exception asd)
            {
                //writetxt("端口名称:" + serialPort1.PortName + "====" + "端口名称:" + "波特率:" + serialPort1.BaudRate + "串口状态:" + serialPort1.IsOpen + "错误信息:" + asd.Message);
                return;
            }
        }
		public void DispUI(byte[] InputBuf)
        {
            //textBox1.Text = Convert.ToString(InputBuf);
             
            string aaa = Encoding.Default.GetString(InputBuf);
            textBox1.Text = aaa;
           // writetxt("端口名称:" + serialPort1.PortName + "====" + "端口名称:" + "波特率:" + serialPort1.BaudRate + "串口状态:" + serialPort1.IsOpen + "错误信息:无     " + "数据:" + aaa);

        }

6.模拟串口发送数据

模拟串口调试工具可参考我另一篇文章链接https://blog.csdn.net/qq_39569480/article/details/120776868

在这里插入图片描述

方式2

发送接收 完整代码示例

源码下载地址demo

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;//线程申明

namespace ck3
{
    public partial class Form1 : Form
    {
        private void CheckPort()//检查串口是否可用
        {
            ckCheckBox.Items.Clear();//清除控件中的当前值
            bool havePort = false;
            string[] a = SerialPort.GetPortNames();
            if (a != null)
            {
                
                for (int i = 0; i < a.Length; i++)
                {
                    bool use = false;
                    try
                    {
                        SerialPort t = new SerialPort(a[i]);
                        sp.Open();
                        sp.Close();
                        use = true;
                    }
                    catch
                    {
                    }
                    if (use)
                    {
                        ckCheckBox.Items.Add(a[i]);
                        havePort = true;
                    }
                }
            }
            if (havePort)
            {
                ckCheckBox.SelectedIndex = 0;//??
            }
            else
            {
                MessageBox.Show("无可用串口...", "错误");
            }

        }
        private void SetPort()//设置串口
        {
            try
            {
                sp.PortName = ckCheckBox.Text.Trim();//串口名给了串口类
                sp.BaudRate = Convert.ToInt32(SendBox.Text.Trim());//Trim除去前后空格,讲文本转换为32位字符给予串口类
                if (JywCheckBox.Text.Trim() == "奇校验")
                {
                    sp.Parity = Parity.Odd;//将奇校验位给了sp的协议
                }
                else if (JywCheckBox.Text.Trim() == "偶校验")
                {
                    sp.Parity = Parity.Even;
                }
                else
                {
                    sp.Parity = Parity.None;
                }
                if (StopCheckBox.Text.Trim() == "1.5")
                {
                    sp.StopBits = StopBits.OnePointFive;//设置停止位有几位
                }
                else if (StopCheckBox.Text.Trim() == "2")
                {
                    sp.StopBits = StopBits.Two;
                }
                else
                {
                    sp.StopBits = StopBits.One;
                }
                sp.DataBits = Convert.ToInt16(DataBox.Text.ToString().Trim());//数据位
                sp.Encoding = Encoding.UTF8;//串口通信的编码格式
                sp.Open();
            }
            catch { }

        }
        private string HexToASCII(string str)
        {
            try
            {
                string[] mystr1 = str.Trim().Split(' ');
                byte[] t = new byte[mystr1.Length];
                for (int i = 0; i < t.Length; i++)
                {
                    t[i] = Convert.ToByte(mystr1[i], 16);
                }
                return Encoding.UTF8.GetString(t);

            }
            catch (Exception ex)
            {
                rbtReceicedAscii.Select();
                MessageBox.Show("转换失败!" + ex.Message, "错误提示");
                return str;

            }
        }
        private string ASCIIToHex(string my2)
        {
            try
            {
                byte[] a = Encoding.UTF8.GetBytes(my2.Trim());
                string mystr1 = "";
                for (int i = 0; i < a.Length; i++)
                {
                    mystr1 += a[i].ToString("X2") + " ";
                }
                return mystr1;
            }
            catch (Exception ex)
            {
                rbtReceicedAscii.Select();
                MessageBox.Show("转换失败!" + ex.Message, "错误提示");
                return my2;
            }


        }
       
      

        private void Form1_Load(object sender, EventArgs e)
        {
            statusText.Text = "";//状态条初始化
            //设置窗口大小
            this.MaximizeBox = false;//隐藏最大化按钮
            this.MaximumSize = this.Size;//固定窗口尺寸最大为当前尺寸
            this.MinimumSize = this.Size;//固定窗口尺寸最小为当前尺寸
            BtlCheckBox.SelectedIndex = 5;
          //  JywCheckBox.Items.Clear();
            JywCheckBox.SelectedIndex = 1;
            StopCheckBox.SelectedIndex = 1;
           // DataBox.Items.Clear();
            DataBox.SelectedIndex = 1;
            statusText.Text = "";
            rbtSendAscii.Select();//默认选择ASCII字符显示
            rbtReceicedAscii.Select();//默认选择ASCII字符显示

        }

        private void btnChecked_Click(object sender, EventArgs e)
        {
            statusText.Text = "检测串口开始!";
            CheckPort();
            statusText.Text = "串口检测完成!";
        }
        private void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            Thread.Sleep(100);//等待

            this.Invoke((EventHandler)(delegate //异步委托一个线程
            {
                try
                {
                    byte[] a = new byte[sp.BytesToRead];//读出缓冲区串口通信的字节
                    sp.Read(a, 0, a.Length);//写入sp
                    string my2 = Encoding.UTF8.GetString(a);
                    string b = "";
                    if (rbtSendAscii.Checked)
                    {
                        b = ASCIIToHex(my2);
                    }
                    else
                    {
                        b = my2;
                    }
                    RecevieBox.Text += b + "\r\n";
                    statusText.Text = "接收成功!";
                }
                catch
                {
                    statusText.Text = "接收失败!";
                }
            }));
        }
        public Form1()
        {
            InitializeComponent();
        }
    
   
        //发送按钮
        private void button1_Click_1(object sender, EventArgs e)
        {
            try
            {
                string mystr1 = SendBox.Text;
                if (SixtyRe.Checked)//radio如果选择十六进制    则进行转换
                {
                    mystr1 = HexToASCII(SendBox.Text);
                }
                byte[] a = Encoding.UTF8.GetBytes(mystr1);
                string mystr2 = Encoding.UTF8.GetString(a);
                sp.Write(mystr2);//将数据写入串行端口输出缓冲区
                // tbxReceivedData.Text += tbxSendData.Text + "\r\n";
                statusText.Text = "发送成功!";
            }
            catch
            {
                statusText.Text = "发送失败";
            }
        }

        private void button1_Click_2(object sender, EventArgs e)
        {
            RecevieBox.Text = " ";
            SendBox.Text = " ";
        }

       

        private void BtnOpen_Click(object sender, EventArgs e)
        {
           
                if (BtnOpen.Text == "打开串口")
                {
                    SetPort();
                    if (sp.IsOpen)
                    {
                        statusText.Text = "串口" + ckCheckBox.Text + "已打开!";
                    }
                    else
                    {
                        try
                        {
                            sp.Open();
                            btnChecked.Enabled = false;
                            ckCheckBox.Enabled = false;
                            BtlCheckBox.Enabled = false;
                            JywCheckBox.Enabled = false;
                            StopCheckBox.Enabled = false;
                            DataBox.Enabled = false;
                            BtnOpen.Text = "关闭串口";
                            statusText.Text = "串口" + ckCheckBox.Text + "打开成功!";
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show("串口" + ckCheckBox.Text + "打开失败,失败原因:" + ex.Message, "错误提示");
                            statusText.Text = "串口" + ckCheckBox.Text + "打开失败,失败原因:" + ex.Message;
                        }
                    }
                }
                else //关闭串口
                {
                    if (sp.IsOpen) //判断串口是否打开
                    {
                        try
                        {
                            sp.Close(); //关闭串口
                                        //启用设置控件
                        btnChecked.Enabled = true;
                        ckCheckBox.Enabled = true;
                        BtlCheckBox.Enabled = true;
                        JywCheckBox.Enabled = true;
                        StopCheckBox.Enabled = true;
                        DataBox.Enabled = true;
                        BtnOpen.Text = "打开串口";
                        statusText.Text = "串口" + ckCheckBox.Text + "关闭成功!";
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show("串口" + ckCheckBox.Text + "关闭失败,错误提示:" + ex.Message, "错误提示");
                        statusText.Text = "串口" + ckCheckBox.Text + "关闭失败,错误提示:" + ex.Message;
                        }
                    }
                    else
                    {
                    btnChecked.Enabled = true;
                    ckCheckBox.Enabled = true;
                    BtlCheckBox.Enabled = true;
                    JywCheckBox.Enabled = true;
                    StopCheckBox.Enabled = true;
                    DataBox.Enabled = true;
                    BtnOpen.Text = "打开串口";
                    statusText.Text = "串口未打开,无法关闭!";
                        MessageBox.Show("串口未打开,无法关闭!", "错误提示");
                    }
                

            }

        }

       
        private void SixtySend_CheckedChanged(object sender, EventArgs e)
        {
            if (SixtyRe.Checked)//radio如果选择十六进制    则进行转换
            {
                SendBox.Text = ASCIIToHex(SendBox.Text.ToString());
            }
        }

       
    }
}

  • 1
    点赞
  • 0
    评论
  • 10
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页

打赏作者

香煎三文鱼

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值