C#串口通信

通过COM1发送数据,COM2接收数据。当COM2接收完本次发送的数据后,向COM1发送信息通知COM1本次数据已发完,COM1接到通知后,再发下一段数据。这样可以确保每次发送的数据都可以被正确接收。

代码:

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;

using System.Threading;

using Utils;



namespace 串口通信

{

    public partial class Form1 : Form

    {

        #region 变量

        /// <summary>

        /// 启动还是停止,true起动,false停止

        /// </summary>

        public static bool start = true;

        /// <summary>

        /// 串口资源

        /// </summary>

        private static SerialPort serialPort1 = null;

        /// <summary>

        /// 串口资源

        /// </summary>

        private static SerialPort serialPort2 = null;

        /// <summary>

        /// 成功次数

        /// </summary>

        private static int successCount = 0;

        /// <summary>

        /// 失败次数

        /// </summary>

        private static int errorCount = 0;

        /// <summary>

        /// 上次计算的总次数

        /// </summary>

        private static int lastCount = 0;

        /// <summary>

        /// 定时器

        /// </summary>

        private System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();

        #endregion



        #region Form1

        public Form1()

        {

            InitializeComponent();

        }

        #endregion



        #region Form1_Load

        private void Form1_Load(object sender, EventArgs e)

        {

            serialPort1 = new SerialPort("COM1");

            serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceived1);

            serialPort1.Open();

            serialPort2 = new SerialPort("COM2");

            serialPort2.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceived2);

            serialPort2.Open();

        }

        #endregion



        #region Form1_FormClosed

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)

        {

            serialPort1.Close();

            serialPort1.Dispose();

            serialPort2.Close();

            serialPort2.Dispose();

        }

        #endregion



        #region btnStart_Click

        private void btnStart_Click(object sender, EventArgs e)

        {

            start = true;

            SendData();



            timer.Interval = 500;

            timer.Tick += new EventHandler(delegate(object obj, EventArgs eventArgs)

            {

                if (lastCount == 0)

                {

                    lastCount = successCount + errorCount;

                }

                else

                {

                    int cnt = successCount + errorCount - lastCount;

                    cnt = Data.Length * cnt / 1024 * (1000 / timer.Interval);

                    double total = (successCount + errorCount) * Data.Length / 1024.0;



                    InvokeDelegate invokeDelegate = delegate()

                    {

                        label3.Text = cnt.ToString() + "KB/S " + total.ToString("#.0") + "KB";

                    };

                    InvokeUtil.Invoke(this, invokeDelegate);

                    lastCount = successCount + errorCount;

                }

            });

            timer.Start();

        }

        #endregion



        #region btnStop_Click

        private void btnStop_Click(object sender, EventArgs e)

        {

            start = false;

            timer.Stop();

            timer.Dispose();

            timer = new System.Windows.Forms.Timer();

        }

        #endregion



        #region 接收串口数据事件

        /// <summary>

        /// 接收串口数据事件

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        public void serialPort_DataReceived1(object sender, SerialDataReceivedEventArgs e)

        {

            if (serialPort1.ReadLine() != null)

            {

                successCount++;

                SendData();

            }

        }



        /// <summary>

        /// 接收串口数据事件

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        public void serialPort_DataReceived2(object sender, SerialDataReceivedEventArgs e)

        {

            List<byte> bList = new List<byte>();

            int i = 0;

            while (serialPort2.BytesToRead > 0)

            {

                byte[] bArr = new byte[serialPort2.BytesToRead];

                i += serialPort2.Read(bArr, 0, bArr.Length);

                bList.AddRange(bArr);

            }

            serialPort2.WriteLine("success");



            string s = ASCIIEncoding.UTF8.GetString(bList.ToArray());

            InvokeDelegate invokeDelegate = delegate()

            {

                textBox2.Text = s;

            };

            InvokeUtil.Invoke(this, invokeDelegate);



            if (s != Str)

            {

                errorCount++;

                invokeDelegate = delegate()

                {

                    label2.Text = errorCount + "次不相等(失败)";

                };

                InvokeUtil.Invoke(this, invokeDelegate);

            }

            else

            {

                invokeDelegate = delegate()

                {

                    label1.Text = successCount + "次相等(成功)";

                };

                InvokeUtil.Invoke(this, invokeDelegate);

            }

        }

        #endregion



        #region 发送数据

        private void SendData()

        {

            if (start)

            {

                Thread thread = new Thread(new ParameterizedThreadStart(delegate(object obj)

                {

                    InvokeDelegate invokeDelegate = delegate()

                    {

                        textBox1.Text = Str;

                    };

                    InvokeUtil.Invoke(this, invokeDelegate);



                    serialPort1.Write(Data, 0, Data.Length);

                }));

                thread.Start();

            }

        }

        #endregion



        #region 数据

        private static byte[] data = null;

        /// <summary>

        /// 数据

        /// </summary>

        private static byte[] Data

        {

            get

            {

                if (data == null)

                {

                    data = ASCIIEncoding.UTF8.GetBytes(Str);

                }



                return data;

            }

        }

        #endregion



        #region 获取字符串

        private static string str = null;

        /// <summary>

        /// 字符串

        /// </summary>

        private static string Str

        {

            get

            {

                if (str == null)

                {

                    StringBuilder sb = new StringBuilder();

                    for (int i = 0; i < 270; i++)

                    {

                        sb.Append("计算机程序");

                    }

                    str = sb.ToString();

                }



                return str;

            }

        }

        #endregion



    }

}
View Code

辅助代码:

using System;

using System.Collections.Generic;

using System.Text;

using System.Windows.Forms;



namespace Utils

{

    /// <summary>

    /// 跨线程访问控件的委托

    /// </summary>

    public delegate void InvokeDelegate();



    /// <summary>

    /// 跨线程访问控件类

    /// </summary>

    public class InvokeUtil

    {

        /// <summary>

        /// 跨线程访问控件

        /// </summary>

        /// <param name="ctrl">Form对象</param>

        /// <param name="de">委托</param>

        public static void Invoke(Control ctrl, Delegate de)

        {

            if (ctrl.IsHandleCreated)

            {

                ctrl.BeginInvoke(de);

            }

        }

    }

}
View Code

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using Microsoft.Win32;

using System.Security.Permissions;

using System.IO.Ports;

using System.Security;



namespace Utils

{

    /// <summary>

    /// 串口资源工具类

    /// </summary>

    public class SerialPortUtil

    {

        #region 获取本机串口列表,包括虚拟串口

        /// <summary>

        /// 获取本机串口列表,包括虚拟串口

        /// </summary>

        public static string[] GetCOMList()

        {

            List<string> list = new List<string>();



            foreach (string portName in SerialPort.GetPortNames())

            {

                list.Add(portName);

            }



            return list.ToArray();

        }

        #endregion



        #region 从注册表获取本机串口列表

        /// <summary>

        /// 从注册表获取本机串口列表

        /// </summary>

        public static string[] GetPortNames()

        {

            RegistryKey localMachine = null;

            RegistryKey key2 = null;

            string[] textArray = null;



            //这里有个断言,判断该注册表项是否存在

            new RegistryPermission(RegistryPermissionAccess.Read, @"HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM").Assert();



            try

            {

                localMachine = Registry.LocalMachine;

                key2 = localMachine.OpenSubKey(@"HARDWARE\DEVICEMAP\SERIALCOMM", false);

                if (key2 != null)

                {

                    string[] valueNames = key2.GetValueNames();

                    textArray = new string[valueNames.Length];

                    for (int i = 0; i < valueNames.Length; i++)

                    {

                        textArray[i] = (string)key2.GetValue(valueNames[i]);

                    }

                }

            }

            finally

            {

                if (localMachine != null)

                {

                    localMachine.Close();

                }

                if (key2 != null)

                {

                    key2.Close();

                }

                CodeAccessPermission.RevertAssert();

            }

            if (textArray == null)

            {

                textArray = new string[0];

            }

            return textArray;

        }

        #endregion



    }

}
View Code

 

你可能感兴趣的:(C#)