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 = ;
/// <summary>
/// 失败次数
/// </summary>
private static int errorCount = ;
/// <summary>
/// 上次计算的总次数
/// </summary>
private static int lastCount = ;
/// <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 = ;
timer.Tick += new EventHandler(delegate(object obj, EventArgs eventArgs)
{
if (lastCount == )
{
lastCount = successCount + errorCount;
}
else
{
int cnt = successCount + errorCount - lastCount;
cnt = Data.Length * cnt / * ( / 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 = ;
while (serialPort2.BytesToRead > )
{
byte[] bArr = new byte[serialPort2.BytesToRead];
i += serialPort2.Read(bArr, , 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, , 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 = ; i < ; 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 = ; 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[];
}
return textArray;
}
#endregion }
}
C#串口通信的更多相关文章
- .NET 串口通信
这段时间做了一个和硬件设备通信的小项目,涉及到扫描头.输送线.称重机.贴标机等硬件.和各设备之间通信使用的是串口或网络(Socket)的方式.扫描头和贴标机使用的网络通信,输送线和称重机使用的是串口通 ...
- BluetoothChat用于蓝牙串口通信的修改方法
本人最近在研究嵌入式的串口通信,任务是要写一个手机端的遥控器用来遥控双轮平衡小车.界面只用了一个小时就写好了,重要的问题是如何与板子所带的SPP-CA蓝牙模块进行通信. SPP-CA模块自带代码,在这 ...
- Win10 IoT C#开发 4 - UART 串口通信
Windows 10 IoT Core 是微软针对物联网市场的一个重要产品,既可以开发设备UI与用户交互式操作,又可以控制GPIO等接口,使得原来嵌入式繁琐的开发变得简单.通过Remote Debug ...
- 使用Java实现简单串口通信
最近一门课要求编写一个上位机串口通信工具,我基于Java编写了一个带有图形界面的简单串口通信工具,下面详述一下过程,供大家参考 ^_^ 一: 首先,你需要下载一个额外的支持Java串口通信操作的jar ...
- Java 串口通信
在Windows系统下,用Java开发串口通信相关的程序时,需要用到几个文件. (1)win32com.dll 要放在jdk\jre\bin目录下. (2)comm.jar 和javax.comm.p ...
- .NET 串口通信中断接收,包含0X1A(作为EOF)
.NET串口通信中将`0X1A`当做EOF处理,.NET接收到EOF会触发一次接收中断,此时事件形参`SerialDataReceivedEventArgs`值为枚举 `Eof`,其他为`Chars` ...
- STC12C5A60S2 双串口通信
STC12C5A60S2单片机是一款功能比较强大的单片机,它拥有两个全双工串行通信接口,串口1的功能及操作与传统51单片机串行口相同:特殊的是STC12C5A60S2单片机内部有一个独立波特率发生器, ...
- mfc 调用Windows的API函数实现同步异步串口通信(源码)
在工业控制中,工控机(一般都基于Windows平台)经常需要与智能仪表通过串口进行通信.串口通信方便易行,应用广泛. 一般情况下,工控机和各智能仪表通过RS485总线进行通信.RS485的通信方式是半 ...
- VS2008基于对话框的MFC上位机串口通信(C++实现)简单例程
首先,在 vs2008 环境下创建 MFC 运用程序 设置项目名称为 ComTest(这个地方随意命名,根据个人习惯),点击确定后,点击下一步 出现如下界面 选择"基于对话框"模式 ...
- C语言dsPIC / PIC24 serial bootloader和C#语言bootloader PC端串口通信程序
了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). 新dsPIC/PIC2 ...
随机推荐
- 【css3】--四种气泡
在聊天的场景中,聊天内容需要用到气泡修饰,如下图.下面一一讲解. 图片式: 第一个样式是京东客服,气泡的圆角和钩子都是用了图片.使用了一个table组合成了一个圆角的框框.lm样式拼出了钩子. < ...
- Hello Mybatis 01 第一个CRUD
What's the Mybatis? MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google c ...
- http学习笔记(三)
几乎所有的http通信都是由TCP/IP承载的.http好比一辆汽车,而TCP是一条公路,所有的汽车都要在公路上跑,看看http是如何在tcp这条公路上往返的. 首先简单地看看tcp,TCP连接是通过 ...
- 十分钟搞定CSS选择器
在最近的web开发中是不是就会用到一些选择器,发现很多尤其是CSS3新增的不太熟悉,在此总结一下. 优先级 不同级别 1. 在属性后面使用 !important 会覆盖页面内任何位置定义的元素样式. ...
- redis源码系列-数据结构(adlist/ziplist/dict)
该系列基于redis-2.8.18,主要记录自己的理解或者想法.redis以自己支持存储的数据结构丰富吸引了大批人,把memcached比了下去.本文就从简单基本的数据结构入手. 双向链表-adlis ...
- 【团队分享之二】IT团队绩效提升的一些见解
- js笔记——js数据类型转换
以下内容摘录自阮一峰的<语法概述 -- JavaScript 标准参考教程(alpha)>章节『数据类型转换』,以做备忘.更多内容请查看原文. JavaScript是一种动态类型语言,变量 ...
- Programming in lua 杂记(转)
1,loadstring 编译的时候不关心词法范围: local i = 0 f = loadstring("i = i + 1") g = function () i = ...
- Atitit.软件与编程语言中的锁机制原理attilax总结
Atitit.软件与编程语言中的锁机制原理attilax总结 1. 用途 (Db,业务数据加锁,并发操作加锁.1 2. 锁得类型 排它锁 "互斥锁 共享锁 乐观锁与悲观锁1 2.1. 自旋锁 ...
- OutputCache属性详解(四)— SqlDependency
目录 OutputCache概念学习 OutputCache属性详解(一) OutputCache属性详解(二) OutputCache属性详解(三) OutputCache属性详解(四)— SqlD ...