ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Winfrom实现串口通信工具

2022-06-23 20:34:30  阅读:114  来源: 互联网

标签:return string Settings Winfrom void ComPort 通信 串口 public


一、简介

要想实现该功能,需要对C#有一些基本的了解

二、实现步骤

2.1 实例化一个SerialPort 对象 

SerialPort ComPort = new SerialPort();

2.2设置串口参数

ComPort.PortName = “COM3”;//串口号
ComPort.BaudRate = 9600;//波特率
ComPort.Parity = Parity.Even;//校验位
ComPort.DataBits = 8;//数据位长度
ComPort.StopBits = StopBits.One;//停止位

2.3打开串口

     public void Open()
        {
            ComPort.Open();
            ComPort.DataReceived += new SerialDataReceivedEventHandler(m_Serial_DataReceived);
        }
        public void m_Serial_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            Thread.Sleep(100);
            try
            {
                byte[] byteRead = new byte[ComPort.BytesToRead];
                ComPort.Read(byteRead, 0, byteRead.Length);
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

打开串口时,订阅DataReceived事件,当串口接收到数据时,就会调用方法 m_Serial_DataReceived(object sender, SerialDataReceivedEventArgs e),使用 SerialPort.Read(byte[] buffer, int offset, int count)将数据从缓存区中取出来;

2.4 发送数据 使用SerialPort.Write(string text)发送数据

    public bool SendDate(string str)
        {
            try
            {
                if (ComPort.IsOpen)
                {

                    ComPort.Write(str);
                }
                else
                {
                    return false;
                }
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }

2.5 关闭串口 使用SerialPort..Close(),并且取消事件订阅

    public void Close()
        {
            ComPort.Close();
            ComPort.DataReceived -= new SerialDataReceivedEventHandler(m_Serial_DataReceived);
        }

 

三、使用Winfrom实现

3.1 界面实现

3.2  后台代码实现

 3.2.1 新建类UsualCom,将SerialPort实习的收发等功能放在该类里实现

public class UsualCom
    {

        public SerialPort ComPort;
        static ReaderWriterLockSlim LogWriteLock = new ReaderWriterLockSlim();
        public UI m_ui = null;

        public UsualCom(UI ui)
        {
            ComPort = new SerialPort();
            ComPort.WriteBufferSize = 1024;
            m_ui = ui;
        }
        public bool IsOpen
        {
            get { return ComPort.IsOpen; }
        }
        public string PortName
        {

            get { return ComPort.PortName; }
            set { ComPort.PortName = value; }
        }
        public int BaudRate
        {
            get { return ComPort.BaudRate; }
            set { ComPort.BaudRate = value; }
        }
        public Parity Parity
        {
            get { return ComPort.Parity; }
            set { ComPort.Parity = value; }
        }
        public int DataBits
        {
            get { return ComPort.DataBits; }
            set { ComPort.DataBits = value; }
        }
        public int ReadTimeout
        {
            get { return ComPort.ReadTimeout; }
            set { ComPort.ReadTimeout = value; }
        }
        public int WriteTimeout
        {
            get { return ComPort.WriteTimeout; }
            set { ComPort.WriteTimeout = value; }
        }
        public StopBits StopBits
        {
            get { return ComPort.StopBits; }
            set { ComPort.StopBits = value; }
        }

        /// <summary>
        /// 串口发送
        /// </summary>
        public bool SendDate(byte[] Buff, int nplace)
        {
            try
            {
                if (ComPort.IsOpen)
                {

                    ComPort.Write(Buff, 0, nplace);
                }
                else
                {
                    return false;// Open();
                }
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }
        public bool SendDate(string str)
        {
            try
            {
                if (ComPort.IsOpen)
                {

                    ComPort.Write(str);
                }
                else
                {
                    return false;
                }
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }


        public void Open()
        {
            ComPort.Open();
            ComPort.DataReceived += new SerialDataReceivedEventHandler(m_Serial_DataReceived);
        }
        public void Close()
        {
            ComPort.Close();
            ComPort.DataReceived -= new SerialDataReceivedEventHandler(m_Serial_DataReceived);
        }

        /// <summary>
        /// 初始化打开串口
        /// </summary>
        public bool InitOpenPort()
        {
            if (IsOpen)
            {
                Close();
            }
            try
            {
                Open();
            }
            catch (Exception e)
            {
                Close();
                return false;
            }
            return true;
        }
        /// <summary>
        /// 关闭串口
        /// </summary>
        public bool CloseOpenPort()
        {
            try
            {
                if (IsOpen)
                {
                    Close();
                }
            }
            catch (Exception e)
            {
                return false;
            }
            return true;
        }




        /// <summary>
        /// 串口接收
        /// </summary>
        public void m_Serial_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            Thread.Sleep(100);
            try
            {
                byte[] byteRead = new byte[ComPort.BytesToRead];
                ComPort.Read(byteRead, 0, byteRead.Length);
                string msg = "";
                msg = System.Text.Encoding.ASCII.GetString(byteRead);
                msg = ByteArray2String(byteRead) + "\r\n";
                putlog(msg);
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }


        /// <summary>
        /// 实现界面信息打印
        /// </summary>
        /// <param name="msg"></param>
        public void putlog(string msg)
        {
            string s = "";
            s = DateTime.Now.ToString("[yyyy-MM-dd HH:mm:ss fff]") + " " + msg + s + "\r\n";
            m_ui.ShowMsgToFormMain(s);
            WriteLog(s);
        }

        /// <summary>
        /// 日志打印
        /// </summary>
        /// <param name="logstr"></param>
        private static void WriteLog(string logstr)
        {
            try
            {
                LogWriteLock.EnterReadLock();
                string sFilePath = Directory.GetCurrentDirectory() + "\\log\\" + DateTime.Now.ToString("yyyyMM");
                string sFileName = DateTime.Now.ToString("yyyyMMdd") + ".log";
                sFileName = sFilePath + "\\" + sFileName; //文件的绝对路径
                if (!Directory.Exists(sFilePath))//验证路径是否存在
                {
                    Directory.CreateDirectory(sFilePath);
                    //不存在则创建
                }
                FileStream fs;
                StreamWriter sw;
                if (File.Exists(sFileName))
                {
                    fs = new FileStream(sFileName, FileMode.Append, FileAccess.Write);

                }
                else
                {
                    fs = new FileStream(sFileName, FileMode.Create, FileAccess.Write);

                }
                sw = new StreamWriter(fs);
                sw.Write(logstr);
                sw.Close();
                fs.Close();
            }
            catch
            { }

        }
        public string ByteArray2String(byte[] buff)
        {


            string s = "";
            for (int i = 0; i < buff.Length; i++)
            {
                s += buff[i].ToString("X2") + " ";
            }
            return s;
        }
        public byte[] string2ByteL(string value)
        {
            string send = value.Replace(" ", "");
            int length = send.Length / 2;
            byte[] rtu = new byte[length];
            for (int i = 0; i < length; i++)
            {
                rtu[i] = Bin2BCD(send.Substring(i * 2, 2));
            }
            return rtu;
        }
        public byte Bin2BCD(string binValue)
        {
            int Value = Convert.ToInt32(binValue, 16);
            return (byte)Value;
        }
        public string ByteArray2Ascii(byte[] value)
        {
            string s = "";
            for (int i = 0; i < value.Length; i++)
            {
                s += Encoding.ASCII.GetString(value);
            }
            return s;
        }

    }

3.2.2 将需要通知到UI线程的委托事件也放置在UI类里面

public class UI
    {
        public delegate void ShowMsg(string msg);
        public event ShowMsg OnShowMsg;


        public void ShowMsgToFormMain(string msg)
        {
            OnShowMsg(msg);
        }
    }

3.2.3 窗体后台代码

 public partial class MainForm : Form
    {
        public delegate void ShowData(string msg);
        private UI m_UI = null;
        private UsualCom gzComport = null;

        public MainForm()
        {
            InitializeComponent();
            Initcontrol();
        }
        private void Initcontrol()
        {
            string[] str = System.IO.Ports.SerialPort.GetPortNames();
            foreach (string s in str)
            {
                cboxPort.Items.Add(s);
            }

            int[] Bps = { 9600, 57600, 115200, 256000, 512000, 921600, 1228800 };
            List<int> listBps = new List<int>(Bps);
            foreach (int T in listBps)
            {
                cboxBandRate.Items.Add(T);
            }

            float[] Spb = { 1, 2 };
            foreach (float B in Spb)
            {
                cboxStopBit.Items.Add(B);
            }

            string[] strParity = { "无校验", "奇校验", "偶校验" };
            foreach (string st in strParity)
            {
                cboxParity.Items.Add(st);
            }

            cboxStopBit.SelectedIndex = Settings.Default.cboxStopBit;
            cboxBandRate.SelectedIndex = Settings.Default.cboxBandRate;
            cboxPort.SelectedIndex = Settings.Default.cboxPort;
            cboxParity.SelectedIndex = Settings.Default.cboxParity;

            rbtnHexModeS1.Checked = Settings.Default.rbtnHexModeS1;
            rbtnHexModeS2.Checked = Settings.Default.rbtnHexModeS2;
            rbtnHexModeS3.Checked = Settings.Default.rbtnHexModeS3;
            rbtnTextModeS1.Checked = Settings.Default.rbtnTextModeS1;
            rbtnTextModeS2.Checked = Settings.Default.rbtnTextModeS2;
            rbtnTextModeS3.Checked = Settings.Default.rbtnTextModeS3;
            rbtnHexModeR.Checked = Settings.Default.rbtnHexModeR;
            rbtnTextModeR.Checked = Settings.Default.rbtnTextModeR;
            m_UI = new UI();
            gzComport = new UsualCom(m_UI);
            m_UI.OnShowMsg += ShowMsgInvoke;
        }
        /// <summary>
        /// 保存参数
        /// </summary>
        public void Save()
        {
            Settings.Default.cboxPort = cboxPort.SelectedIndex;
            Settings.Default.cboxBandRate = cboxBandRate.SelectedIndex;
            Settings.Default.cboxParity = cboxParity.SelectedIndex;
            Settings.Default.cboxParity = cboxParity.SelectedIndex;
            Settings.Default.rbtnHexModeS1 = rbtnHexModeS1.Checked;
            Settings.Default.rbtnHexModeS2 = rbtnHexModeS2.Checked;
            Settings.Default.rbtnHexModeS3 = rbtnHexModeS3.Checked;
            Settings.Default.rbtnTextModeS1 = rbtnTextModeS1.Checked;
            Settings.Default.rbtnTextModeS2 = rbtnTextModeS2.Checked;
            Settings.Default.rbtnTextModeS3 = rbtnTextModeS3.Checked;

            Settings.Default.Save();
        }
        private void btnOpen_Click(object sender, EventArgs e)
        {
            if (cboxPort.Items.Count <= 0)
            {
                MessageBox.Show("没有发现串口,请检查端口!");
                return;
            }
            if (btnOpen.Text == "打开串口")
            {
                gzComport.PortName = cboxPort.SelectedItem.ToString();
                gzComport.BaudRate = Convert.ToInt32(cboxBandRate.SelectedItem);
                gzComport.DataBits = 8;

                switch (cboxParity.SelectedIndex)
                {
                    case 0:
                        gzComport.Parity = Parity.None;
                        break;
                    case 1:
                        gzComport.Parity = Parity.Odd;
                        break;
                    case 2:
                        gzComport.Parity = Parity.Even;
                        break;
                    default: break;
                }

                switch (cboxStopBit.SelectedIndex)
                {
                    case 0:
                        gzComport.StopBits = StopBits.One;
                        break;
                    case 1:
                        gzComport.StopBits = StopBits.Two;
                        break;
                    case 2:
                        gzComport.StopBits = StopBits.OnePointFive;
                        break;
                    case 3:
                        gzComport.StopBits = StopBits.Two;
                        break;
                    default: break;
                }
                gzComport.ReadTimeout = 1000;
                gzComport.WriteTimeout = 1000;
                if (gzComport.InitOpenPort())
                {
                    gzComport.putlog("打开串口成功");
                }
                else
                {
                    gzComport.putlog("打开串口失败");
                }
                cboxPort.Enabled = false;
                cboxBandRate.Enabled = false;
                cboxStopBit.Enabled = false;
                cboxParity.Enabled = false;
                btnOpen.Text = "关闭串口";

            }
            else if (btnOpen.Text == "关闭串口")
            {
                if (gzComport.CloseOpenPort())
                {
                    gzComport.putlog("串口关闭成功");
                }
                cboxPort.Enabled = true;
                cboxBandRate.Enabled = true;
                cboxStopBit.Enabled = true;
                cboxParity.Enabled = true;
                btnOpen.Text = "打开串口";
            }
            Save();//保存参数
        }
        /// <summary>
        /// 数据发送
        /// </summary>
        /// <param name="cmd"> 命令</param>
        /// <param name="check"> 模式</param>
        public void SendData(string cmd, bool mode)
        {
            if (cmd == "" || cmd == string.Empty)
            {
                return;
            }
            gzComport.putlog(cmd + "\r\n");
            if (mode)
            {
                gzComport.SendDate(cmd);
            }
            else
            {
                gzComport.SendDate(gzComport.string2ByteL(cmd), gzComport.string2ByteL(cmd).Length);
            }
        }
        private void btnSend1_Click(object sender, EventArgs e)
        {

            string cmd = rtbDataSend1.Text.Trim();
            SendData(cmd, rbtnTextModeS1.Checked);
        }
        private void btnSend2_Click(object sender, EventArgs e)
        {
            string cmd = rtbDataSend2.Text.Trim();
            SendData(cmd, rbtnTextModeS2.Checked);
        }
        private void btnSend3_Click(object sender, EventArgs e)
        {
            string cmd = rtbDataSend3.Text.Trim();
            SendData(cmd, rbtnTextModeS3.Checked);
        }

        public void ShowMsgInvoke(string msg)
        {
            if (this.rtbDataR.InvokeRequired)
            {
                ShowData show = new ShowData(ShowMsgInvoke);
                this.rtbDataR.Invoke(show, new object[] { msg });
            }
            else
            {
                this.rtbDataR.AppendText(msg);
                this.rtbDataR.SelectionStart = rtbDataR.Text.Length;
                this.rtbDataR.SelectionLength = 0;
                this.rtbDataR.ScrollToCaret();
            }
        }
        private void btnClear1_Click(object sender, EventArgs e)
        {
            rtbDataSend1.Clear();
        }
        private void btnClear2_Click(object sender, EventArgs e)
        {
            rtbDataSend2.Clear();
        }
        private void btnClear3_Click(object sender, EventArgs e)
        {
            rtbDataSend3.Clear();
        }
        private void btnRecClear_Click(object sender, EventArgs e)
        {
            rtbDataR.Clear();
        }
    }

四、实现效果 (界面上的功能并非全部实现)

 

 

标签:return,string,Settings,Winfrom,void,ComPort,通信,串口,public
来源: https://www.cnblogs.com/just-like/p/16406610.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有