欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C.Net串口工具源码 串口调试工具 支持16进制发送 可以定时自动发送

程序员文章站 2022-07-03 11:37:34
软件功能: 使用C#实现PC串口通讯 支持定时发送 支持16进制(hex) ASCII UTF-8 Unicode 四种编码格式 支持配置文件的保存和读取 可以可以显示发送历史 可以统计总的发送字节数和接受字节数 软件界面: C#源码: using System; using System.Coll ......

软件功能:

 

使用C#实现PC串口通讯

支持定时发送

支持16进制(hex) ASCII UTF-8 Unicode 四种编码格式

支持配置文件的保存和读取

可以可以显示发送历史

可以统计总的发送字节数和接受字节数

软件界面:

 

C.Net串口工具源码 串口调试工具 支持16进制发送 可以定时自动发送

 

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;
using System.IO.Ports;
using System.Threading;
using System.IO;
using System.Xml.Serialization;
 
namespace 串口调试工具
{
    public partial class Form1 : Form
    {
        private SerialPort sp = new SerialPort();//链接对象
        Config config = new Config();//配置文件
 
        public Form1()
        {
            InitializeComponent();
        }
 
        private void Form1_Load(object sender, EventArgs e)
        {
            //获取串口列表
            string[] comList = SerialPort.GetPortNames();
            if (comList.Length == 0)
            {
                MessageBox.Show("无可用串口");
                return;
            }
            foreach (var com in comList)
            {
                cmbComList.Items.Add(com);
            }
 
 
            //添加波特率
            int[] baudRate = { 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 43000, 56000, 57600, 115200 };
            foreach (var br in baudRate)
            {
                cmbBautRade.Items.Add(br);
            }
 
            //添加数据位
            int[] dataBits = { 8, 7, 6, 5 };
            foreach (var db in dataBits)
            {
                cmbDataBits.Items.Add(db);
            }
 
            //添加停止位
            int[] stopBits = { 1, 2, 3 };
            foreach (var sb in stopBits)
            {
                cmbStopBits.Items.Add(sb);
            }
 
            //添加检验方式
            string[] parity = { "None", "Even", "Mark", "Odd", "Space" };
            foreach (var p in parity)
            {
                cmbParity.Items.Add(p);
            }
 
            //添加常用编码
            string[] encode = { "ASCII","UTF-8","Unicode","Hex"};
            foreach (var en in encode)
            {
                cmbEncodeSend.Items.Add(en);
                cmbEncodeRec.Items.Add(en);
            }
 
            //加载配置文件
            LoadConfig();
        }
 
        private void LoadConfig()
        {
            //把配置信息赋值给控件默认值
            cmbComList.SelectedItem = config.PortName;
            if (cmbComList.SelectedIndex == -1) cmbComList.SelectedIndex = 0;
            cmbBautRade.SelectedItem = config.BautRade;
            cmbDataBits.SelectedItem = config.DataBits;
            cmbStopBits.SelectedItem = config.StopBits;
            cmbParity.SelectedItem = config.Parity;
            cmbEncodeRec.SelectedItem = config.EncodeRec;
            cmbEncodeSend.SelectedItem = config.EncodeSend;
 
            //激活打开按钮
            this.btnOpen.Enabled = true;
        }
 
        private void btnOpen_Click(object sender, EventArgs e)
        {
            if (((Button)sender).Text == "打开串口")
            {
                //赋值给串口
                sp.PortName = cmbComList.SelectedItem.ToString();
                sp.Parity=(Parity)Enum.Parse(typeof(Parity),cmbParity.SelectedItem.ToString());
                sp.BaudRate = Convert.ToInt32(cmbBautRade.SelectedItem.ToString());
                sp.StopBits = (StopBits)Convert.ToInt32(cmbStopBits.SelectedItem.ToString());
                sp.DataBits = Convert.ToInt32(cmbDataBits.SelectedItem.ToString());
 
                try
                {
                    sp.Open();
 
                    //修改控件状态
                    this.btnOpen.Text = "关闭串口";
                    foreach (Control ctr in groupBox1.Controls)
                    {
                        //把下拉框全部禁用
                        ctr.Enabled = false;
                    }
 
                    //开启新线程,监听收取内容
                    Thread thread = new Thread(receive);
                    thread.Start();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            else
            {
                if (this.btnAutoSend.Text == "停止发送")
                {
                    MessageBox.Show("当前定时发送中,请先停止定时发送任务.");
                    return;
                } 
                sp.Close();
 
                //修改控件状态
                this.btnOpen.Text = "打开串口";
                foreach (Control ctr in this.groupBox1.Controls)
                {
                    ctr.Enabled = true;
                }
            }
        }
 
        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            //窗体关闭时关闭端口
            sp.Close();
        }
 
        private void btnSend_Click(object sender, EventArgs e)
        {
            Send();
        }
 
        private void btnAutoSend_Click(object sender, EventArgs e)
        {
            if (this.btnAutoSend.Text == "定时发送")
            {
                //根据打开按钮状态初步检查端口是否已经打开
                if (this.btnOpen.Text == "打开串口") return;
 
                System.Text.RegularExpressions.Regex reg1 = new System.Text.RegularExpressions.Regex(@"^[0-9]\d*$");
                if (reg1.IsMatch(txtTime.Text.ToString()))
                {
                    //激活Timer定时器
                    this.timer1.Interval = Convert.ToInt32(txtTime.Text.ToString());
                    this.timer1.Start();
 
                    //修改控件状态
                    this.btnAutoSend.Text = "停止发送";
                    this.btnSend.Enabled = false;
 
                }
                else
                {
                    MessageBox.Show("发送间隔应为正整数");
                    txtTime.Text = "1000";
                }
            }
            else
            {
                this.btnAutoSend.Text = "定时发送";
                this.btnSend.Enabled = true;
                this.timer1.Stop();
            }
        }
 
        private void Send()
        {
            if (sp.IsOpen)
            {
                //获取字节
                byte[] buffer = Encode();
                if (buffer.Length == 0) return;
 
                try
                {
                    sp.Write(buffer, 0, buffer.Length);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
 
                //添加发送历史
                this.txtHistory.AppendText(string.Format("[{0}] {1} \r\n", DateTime.Now.ToString("HH:mm:ss.ff"), txtSend.Text));
                //统计发送字节
                this.labSendCount.Text = (Convert.ToInt32(labSendCount.Text) + buffer.Length).ToString();
            }
            else
            {
                this.timer1.Stop();
                MessageBox.Show("串口尚未打开");
                this.btnAutoSend.Text = "定时发送";
            }
        }
 
        private void timer1_Tick(object sender, EventArgs e)
        {
            //定时发送
            Send();
        }
 
        //字节反编码
        private byte[] Encode()
        {
            byte[] buffer = null;
 
            switch (this.cmbEncodeSend.SelectedItem.ToString())
            {
                case "Unicode":
                    buffer = Encoding.Unicode.GetBytes(txtSend.Text); 
                    break;
                case "UTF-8":
                    buffer = Encoding.UTF8.GetBytes(txtSend.Text);
                    break;
                case "ASCII":
                    buffer = Encoding.ASCII.GetBytes(txtSend.Text);
                    break;
                case "Hex":
                    buffer = strToToHexByte(txtSend.Text);
                    break;
            }
 
            return buffer;
        }
        //编码
        private string UnEncode(byte[] buffer)
        {
            string str = string.Empty;
 
            switch (this.cmbEncodeSend.SelectedItem.ToString())
            {
                case "Unicode":
                    str = new UnicodeEncoding().GetString(buffer);
                    break;
                case "UTF-8":
                    str = new UTF8Encoding().GetString(buffer);
                    break;
                case "ASCII":
                    str = new ASCIIEncoding().GetString(buffer);
                    break;
                case "Hex":
                    str = byteToHexStr(buffer);
                    break;
            }
 
            return str;
        }
        /// <summary>
        /// 字节数组转16进制字符串
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static string byteToHexStr(byte[] bytes)
        {
            string returnStr = "";
            if (bytes != null)
            {
                for (int i = 0; i < bytes.Length; i++)
                {
                    returnStr += bytes[i].ToString("X2");
                }
            }
            return returnStr;
        }
        /// <summary>
        /// 字符串转16进制字节数组
        /// </summary>
        /// <param name="hexString"></param>
        /// <returns></returns>
        private static byte[] strToToHexByte(string hexString)
        {
            hexString = hexString.Replace(" ", "");
            if ((hexString.Length % 2) != 0)
                hexString += " ";
            byte[] returnBytes = new byte[hexString.Length / 2];
            for (int i = 0; i < returnBytes.Length; i++)
                returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
            return returnBytes;
        }
 
        private void receive()
        {
            //接收信息 先判断是否为打开状态
            while (sp.IsOpen)
            {
                if (sp.BytesToRead == 0) continue;
 
                //准备接收
                byte[] buffer = new byte[sp.BytesToRead];
                try
                {
                    //接受动作
                    sp.Read(buffer, 0, buffer.Length);
 
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
 
                //更新UI信息
                this.Invoke((Action)delegate
                {
                    this.txtRec.AppendText(UnEncode(buffer));
                    //是否自动换行
                    if(cbLine.Checked)
                        this.txtRec.AppendText("\r\n");
 
                    //接收统计信息
                    this.labRecCount.Text = (Convert.ToInt32(this.labRecCount.Text) + buffer.Length).ToString();
                });
            }
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            //清空发送历史
            this.txtHistory.Clear();
        }
 
        private void button2_Click(object sender, EventArgs e)
        {
            //清空接收
            this.txtRec.Clear();
        }
 
        private void btnLoad_Click(object sender, EventArgs e)
        {
            //读取xml文件 序列化对象
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "XML(*.xml)|";
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                string filePath = ofd.FileName;
                if (File.Exists(filePath))
                {
                    try
                    {
                        var mySerializer = new XmlSerializer(typeof(Config));
                        using (var sr = new StreamReader(new FileStream(filePath, FileMode.Open, FileAccess.Read)))
                        {
                            config = (Config)mySerializer.Deserialize(sr);
                        }
                        LoadConfig();
                    }
                    catch (Exception ee)
                    {
                        MessageBox.Show(ee.Message);
                    }
                }
                else
                {
                    MessageBox.Show("文件不存在");
                }
            }
        }
 
        private void btnSave_Click(object sender, EventArgs e)
        {
 
            FolderBrowserDialog fbd = new FolderBrowserDialog();            
            if (fbd.ShowDialog() == DialogResult.OK)
            {
                //给对象赋值并序列化保存
                config.PortName = cmbComList.SelectedItem.ToString();
                config.Parity = cmbParity.SelectedItem.ToString();
                config.BautRade = Convert.ToInt32(cmbBautRade.SelectedItem.ToString());
                config.StopBits = Convert.ToInt32(cmbStopBits.SelectedItem.ToString());
                config.DataBits = Convert.ToInt32(cmbDataBits.SelectedItem.ToString());
 
                XmlSerializer xmlFormat=new XmlSerializer(typeof(Config));
                string filePath = fbd.SelectedPath + "\\PortConfig.xml";
                using (Stream stream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None))
                {
                    xmlFormat.Serialize(stream, config);
                }
                MessageBox.Show("成功保存到路径:"+filePath);
            }
        }
 
        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            System.Diagnostics.Process.Start("http://www.chengchenxu.com");  
        }
    }
}

 

 

软件下载:

C.Net串口工具源码 串口调试工具 支持16进制发送 可以定时自动发送串口调试工具.rar

 

源码工程文件:

C.Net串口工具源码 串口调试工具 支持16进制发送 可以定时自动发送串口调试工具.rar

 

虚拟端口软件下载:

C.Net串口工具源码 串口调试工具 支持16进制发送 可以定时自动发送VirtualSerialPortDriver.rar

 

未实现的功能:

16进制校验功能,即发送16进制格式的时候检查输入值是否为正确的16进制数字

接受文件的完整性校验功能,有时候一条信息会分两次接受完整

 

本文为博主原创,转载请保留出处:
http://www.chengchenxu.com/Article/30/