C#串口通信实现方法
作者:shichen2014 发布时间:2023-04-15 06:31:11
本文实例讲述了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);
}
}
}
}
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
}
}
希望本文所述对大家的C#程序设计有所帮助。
猜你喜欢
- 一、什么是稀疏数组当一个数组a中大部分元素为0,或者为同一个值,那么可以用稀疏数组b来保存数组a。首先,稀疏数组是一个数组,然后以一种特定的
- 本文实例为大家分享了C#实现航班预订的具体代码,供大家参考,具体内容如下连接数据库using System;using System.Col
- 一. 析构方法1. 概念我们现在已经知道,构造方法负责创建一个Java的类对象,并可以对该对象进行初始化。与此相对应的,其实还有一个方法,可
- 一、网络爬虫的基本知识网络爬虫通过遍历互联网络,把网络中的相关网页全部抓取过来,这体现了爬的概念。爬虫如何遍历网络呢,互联网可以看做是一张大
- 程序结构:一、配置 1. 在pom.xml中添加依赖pom.xml文件如下:<?xml version="1.0&
- 将网络资源url转化为File文件将互联网上的http开头的url资源,保存到本地。 private File getNetUrlHttp(
- 用java实现简易外卖订餐系统,供大家参考,具体内容如下一、使用技术javaSE二、实现功能外卖订餐系统具体要求如下:使用选择结构,循环结构
- 一、银行存取款1.前言毕竟谁不喜欢钱呢!(不是😅)我看谁不喜欢在知识的海洋中遨游😤!2.描述银行存取款的流程是人们非常熟悉的事情,用户可以在
- 在研究性能的时候,完全可以使用Stopwatch计时器计算一项技术的效率。但是有时想知道某想技术的性能的时候,又常常想不起可以运用Stopw
- 判断某字符串是否为空,为空的标准是str==null或str.length()==01.下面是StringUtils判断是否为空的示例:St
- 一、安装activeMQLinux环境ActiveMQ部署方法:https://www.aspxhome.com/article/16232
- Map是键值对的集合,又叫作字典或关联数组等,是最常见的数据结构之一。在java如何让一个map按value排序呢? 看似简单,但却不容易!
- 快速排序快速排序是一种比较高效的排序算法,采用“分而治之”的思想,通过多次比较和交换来实现排序,在一
- 本文实例讲述了Java继承Thread类创建线程类。分享给大家供大家参考,具体如下:一 点睛通过继承Thread类创建线程并启动多线程的步骤
- 前言在上一篇中,我们初步了解了Sentinel的基本概念,以及其有关限流方面的基础理论,本篇将通过简单的与框架进行整合,看看Sentinel
- Handler每个初学Android开发的都绕不开Handler这个“坎”,为什么说是个坎呢,首先这是Android架构的精髓之一,其次大部
- 这篇文章主要介绍了springboot集成fastDfs过程代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习
- Maven工程分模块开发完成 父工程配置了 tomcat7插件,运行 run命令执行run指令时失败,报错信息如下:D:\java\JDK8
- 在本文中,我们将介绍二进制搜索相对于简单线性搜索的优势,并介绍它在 Java 中的实现。1. 需要有效的搜索假设我们在wine-sellin
- 一.关于使用Mybatisplus自带的selectById和insert方法时的一些问题1.selectById的问题(1).表的主键列名