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
  }
}

 

辅助代码:

 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
  }
}

 

0 0