其他分享
首页 > 其他分享> > Winfrom实现串口通信工具

Winfrom实现串口通信工具

作者:互联网

一、简介

要想实现该功能,需要对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