lemonHe

主要关注FPGA信号处理和数字图像处理技术,欢迎交流 邮箱:heliminlemon@163.com

使用C#设计串口调试助手

0
阅读(3078)

不管是工业的控制系统,还是简单的民用系统,要做控制,都离不开协议,而要实现协议,在PC端需要上位机控制软件,当然,使用通用的串口调试助手也可以,不过需要一串一串指令输入,例如,输入cc 03 01 01 a1 0f eb aa表示做A处理,输入cc 03 02 01 a1 10 eb aa表示做B处理,很烦琐,有么有!!!如果自行设计上位机控制软件,两个Button,一个做A处理,一个做B处理,即可搞定,这样做相当的方便。

下面来介绍简单的串口通信软件设计,并介绍虚拟串口工具的使用。

我使用的软件为VS2010,串口虚拟工具版本为7.2.308。

1. VS2010中新建窗体应用程序

blob.png

2. 添加serialPort组件,微软提供的该组件,方便创建serialPort对象,并集成了与serialPort相关的方法和属性,用起来非常方便。

blob.png    

3. 添加相关控件,设置相关属性包括:

    (1) ComboBox:端口号(cbxPortName)、波特率(cbxBaud)

    (2) Button:打开串口(btnComOpen)、串口发送(btnComSend)

    (3) TextBox:发送框(tbxSend)、接收框(tbxRecv),设置这两个TextBox的 MultiLine属性为true。

    (4) Label:端口号名(labelPortName)、波特率名(Labelbaud)、发送计数(sendCount)、接收计数(labelReceiveCount)

4. 在cbxBaud的Items属性中预设常用波特率

blob.png

5. 添加响应事件

    (1) 添加引用及初始化相关操作

        1) 添加serialPort类引用

                using System.IO.Ports;

        2) 初始化

                string[] str = SerialPort.GetPortNames();

                    if (str == null)

                    {

                    MessageBox.Show("本机没有串口!", "Error");

                    return;

                    }

                    Array.Sort(str);

                    cbxPortName.Items.AddRange(str);

    (2) 串口打开事件

                    private void btnComOpen_Click(object sender, EventArgs e)

                    {

                    }

    (3) 串口发送事件

                    private void btnComSend_Click(object sender, EventArgs e)

                    {

                    }

    (4) 串口接收事件

                private voi d serialPort1_Datareceived(object sender, SerialDataReceivedEventArgs e)

                {

                }

6. 调试

    (1) 软件界面如下,界面非常简单,干净整洁。

blob.png

    (2) 使用虚拟串口工具,虚拟出一对串口,虚拟串口工具下载地址如下

https://pan.baidu.com/s/1c2FxtQC 下载后请参看说明文件,安装完成后先不要打开,使用vspdctl.dll文件覆盖安装目录内的文件即可完成破解。

blob.png

    (3) 开始测试

一端使用写的上位机,另一端使用串口调试助手。

串口调试助手发送一串16进制码,上位机接收,结果如下:

blob.png

上位机发送一串16进制码,串口调试助手接收,结果如下:

blob.png

这个上位机只是完成了简单的串口通信功能,后期再讲讲下位机、上位机进行串口数据解析,如何联系到应用协议,这样才有实际应用价值。

附上实际代码:

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 uartAssist
{
    public partial class Form1 : Form
    {
        private StringBuilder builder = new StringBuilder();        //新建StringBuilder类对象,用来处理可变长度字符串
        static int receiveCount = 0;
        static int sendCount = 0;
        public Form1()
        {            
            InitializeComponent();
            //获取本机串口并添加到cbxPortName中
            string[] str = SerialPort.GetPortNames();
            if (str == null)
            {
                MessageBox.Show("本机没有串口!", "Error");
                return;
            }
            Array.Sort(str);
            cbxPortName.Items.AddRange(str);
            //添加响应事件
            serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_Datareceived);
        }

        static int n = 0;
        static int m = 0;
        private void serialPort1_Datareceived(object sender, SerialDataReceivedEventArgs e)
        {
            n = serialPort1.BytesToRead;
            byte[] datareceive = new byte[n];
            receiveCount += n;
            serialPort1.Read(datareceive, 0, n);

            builder.Remove(0, builder.Length);
            this.Invoke((EventHandler)(delegate
            {
                foreach (byte b in datareceive)
                {
                    builder.Append(b.ToString("X2") + " ");
                }
                this.txtRecv.AppendText(builder.ToString());
                labelReceiveCountNum.Text = receiveCount.ToString();
            }));
        }

        private void btnComOpen_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen)
            {
                serialPort1.Close();
                btnComOpen.Text = "打开";
            }
            else
            {
                serialPort1.PortName = cbxPortName.Text;
                serialPort1.BaudRate = int.Parse(cbxBaud.Text);
                serialPort1.Parity = Parity.None;
                serialPort1.StopBits = StopBits.Two;
                try
                {
                    serialPort1.Open();
                    btnComOpen.Text = "关闭";
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }

        private void btnComSend_Click(object sender, EventArgs e)
        {
            try
            {
                string tbxRecvString = txtSend.Text.ToString();
                string[] tbxRecvs = tbxRecvString.Split(' ');
                m = tbxRecvs.Length;
                byte[] frame = Array.ConvertAll(tbxRecvs, s => Convert.ToByte(s, 16));
                serialPort1.Write(frame, 0, m);
                sendCount += m;
                labelSendCountNum.Text = sendCount.ToString();
            }
            catch (System.Exception ex)
            {
                MessageBox.Show("发送错误:" + ex.Message);
            }
        }

        private void btnCountRst_Click(object sender, EventArgs e)
        {
            labelSendCountNum.Text = "0";
            labelReceiveCountNum.Text = "0";
        }
    }
}