简单的C#串口通讯例子(附源文件)

由于公司需求所以就查了一些资料写了个串口和设备通讯的

    话说现在用串口的应该比较少了吧。
    先上一张程序UI图

这里写图片描述

    简单串口通讯必备的东西都在这里了。个人建议使用的时候先短接2-3口进行测试以免线都不通。
    下面直接上源码,注释写的还是比较详细的相信还是很容易懂的。

(PS:我这里数据接收的结束符为16)

/// <summary>
        /// 创建串口对象
        /// </summary>
        private SerialPort port = new SerialPort();
        /// <summary>
        /// 接受消息
        /// </summary>
        private StringBuilder MsgStr = new StringBuilder();
        /// <summary>
        /// 构造函数
        /// </summary>
        public Form1()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;   //防止跨线程访问出错,好多地方会用到 
        }
        /// <summary>
        /// 窗口加载函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
            ///获取窗口列表
            string[] ports = SerialPort.GetPortNames();
            if (ports.Length > 0)
            {
                ///添加可选通讯口
                com.Items.AddRange(ports);
                ///设置默认选择
                com.SelectedIndex = 0;
                bot.SelectedIndex = 0;
                databit.SelectedIndex = 0;
                stopbit.SelectedIndex = 0;
                jy.SelectedIndex = 0;
            }
            else
            {
                MessageBox.Show("没有可用的串口!");
            }
        }
        /// <summary>
        /// 确认按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                ///检测串口是否开着
                if (!port.IsOpen)
                {
                    ///设置串口名称
                    port.PortName = com.SelectedItem.ToString();
                    ///设置波特率
                    port.BaudRate = Convert.ToInt32(bot.Text);
                    ///数据位
                    port.DataBits = Convert.ToInt32(databit.Text);
                    ///设置无协议
                    port.Handshake = Handshake.None;
                    ///设置读取不超时
                    port.ReadTimeout = -1;
                    //port.WriteTimeout = -1;
                    ///设置停止位
                    port.StopBits = GetStopBits(stopbit.SelectedIndex + 1);

                    port.DtrEnable = true;
                    ///无校验
                    port.Parity = GetParity(jy.SelectedIndex);
                    ///设置数据接收事件
                    port.DataReceived += ReciveData;
                    ///打开串口
                    port.Open();
                    open.Text = "关闭串口";
                    UpdateStutas();
                }
                else
                {
                    ///关闭串口
                    port.Close();
                    port.DataReceived -= ReciveData;
                    open.Text = "打开串口";
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("端口设置错误!");
            }
            finally
            {
                UpdateStutas();
            }
        }
        /// <summary>
        /// 数据接收事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void ReciveData(object sender, SerialDataReceivedEventArgs e)
        {
            ///是否接受完整
            bool isStop = false;
            ///数据长度
            int count = port.BytesToRead;
            string msg = null;
            //{
            byte[] buff = new byte[count];
            ///接收数据
            port.Read(buff, 0, count);
            ///将比特数据转换为字符串
            foreach(byte buf in buff)
            {
                try
                {
                    msg = Convert.ToString(buf, 16);
                    if (msg.Length == 1)
                    {
                        msg = "0" + msg;
                    }
                    if (msg == "16")
                        isStop = true;
                    MsgStr.Append(msg + " ");
                }
                catch (Exception)
                {
                    MessageBox.Show("设备返回不支持的数据!");
                }
            }
            if (!isStop)
                return;
            ///显示数据
            data.Text += "----------------------------\n";
            data.Text += DateTime.Now.ToString() + ":---->" + MsgStr + '\n';
            data.Text += "----------------------------\n";
            MsgStr.Clear();
        }
        /// <summary>
        /// 发送信息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void send_Click(object sender, EventArgs e)
        {
            SendMsg(massage.Text);
        }
        /// <summary>
        /// 获取串口状态
        /// </summary>
        /// <returns></returns>
        private void UpdateStutas()
        {
            if (!port.IsOpen)
                return;
            string stuta = port.PortName + ": " + port.IsOpen.ToString() 
                + " DSR:" + port.DsrHolding + " CDH:" + port.CDHolding + 
                " CTS:" + port.CtsHolding;
            stutas.Text = stuta;
        }
        /// <summary>
        /// 发信
        /// </summary>
        /// <param name="newmsg"></param>
        private void SendMsg(string newmsg)
        {
            if (!port.IsOpen)
            {
                MessageBox.Show("端口已被关闭!");
                return;
            }
            UpdateStutas();
            ///清理残余的缓冲区
            port.DiscardInBuffer();
            port.DiscardOutBuffer();
            ///分割要发送的消息
            string[] sendbuff = newmsg.Split(' ');
            ///发送数据
            List<byte> buf = new List<byte>();//填充到这个临时列表中  

            foreach (string msg in sendbuff)
            {
                try
                {
                    buf.Add(byte.Parse(msg, System.Globalization.NumberStyles.HexNumber));
                }
                catch (Exception)
                {
                    MessageBox.Show(msg + "不是有效的十六进制数字");
                    return;
                }
            }
            //转换列表为数组后发送  
            port.Write(buf.ToArray(), 0, buf.Count);
            //记录发送的字节数  
            sendnum.Text = "发送字节数:" + buf.Count;
        }
        /// <summary>
        /// 获取停止位
        /// </summary>
        /// <param name="num"></param>
        /// <returns></returns>
        private StopBits GetStopBits(int num)
        {
            foreach(StopBits bit in Enum.GetValues(typeof(StopBits)))
            {
                if((int)bit == num)
                {
                    return bit;
                }
            }
            return StopBits.None;
        }
        /// <summary>
        /// 获取校验
        /// </summary>
        /// <param name="num"></param>
        /// <returns></returns>
        private Parity GetParity(int num)
        {
            foreach (Parity bit in Enum.GetValues(typeof(Parity)))
            {
                if ((int)bit == num)
                {
                    return bit;
                }
            }
            return Parity.None;
        }

源文件地址
(ps: DataReceived函数接收的数据不是完整的只要有数据传过来就会产生这个事件,所以最好有自定义的结束符作为标识)

  • 18
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值