通过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#串口通信的更多相关文章

  1. .NET 串口通信

    这段时间做了一个和硬件设备通信的小项目,涉及到扫描头.输送线.称重机.贴标机等硬件.和各设备之间通信使用的是串口或网络(Socket)的方式.扫描头和贴标机使用的网络通信,输送线和称重机使用的是串口通 ...

  2. BluetoothChat用于蓝牙串口通信的修改方法

    本人最近在研究嵌入式的串口通信,任务是要写一个手机端的遥控器用来遥控双轮平衡小车.界面只用了一个小时就写好了,重要的问题是如何与板子所带的SPP-CA蓝牙模块进行通信. SPP-CA模块自带代码,在这 ...

  3. Win10 IoT C#开发 4 - UART 串口通信

    Windows 10 IoT Core 是微软针对物联网市场的一个重要产品,既可以开发设备UI与用户交互式操作,又可以控制GPIO等接口,使得原来嵌入式繁琐的开发变得简单.通过Remote Debug ...

  4. 使用Java实现简单串口通信

    最近一门课要求编写一个上位机串口通信工具,我基于Java编写了一个带有图形界面的简单串口通信工具,下面详述一下过程,供大家参考 ^_^ 一: 首先,你需要下载一个额外的支持Java串口通信操作的jar ...

  5. Java 串口通信

    在Windows系统下,用Java开发串口通信相关的程序时,需要用到几个文件. (1)win32com.dll 要放在jdk\jre\bin目录下. (2)comm.jar 和javax.comm.p ...

  6. .NET 串口通信中断接收,包含0X1A(作为EOF)

    .NET串口通信中将`0X1A`当做EOF处理,.NET接收到EOF会触发一次接收中断,此时事件形参`SerialDataReceivedEventArgs`值为枚举 `Eof`,其他为`Chars` ...

  7. STC12C5A60S2 双串口通信

    STC12C5A60S2单片机是一款功能比较强大的单片机,它拥有两个全双工串行通信接口,串口1的功能及操作与传统51单片机串行口相同:特殊的是STC12C5A60S2单片机内部有一个独立波特率发生器, ...

  8. mfc 调用Windows的API函数实现同步异步串口通信(源码)

    在工业控制中,工控机(一般都基于Windows平台)经常需要与智能仪表通过串口进行通信.串口通信方便易行,应用广泛. 一般情况下,工控机和各智能仪表通过RS485总线进行通信.RS485的通信方式是半 ...

  9. VS2008基于对话框的MFC上位机串口通信(C++实现)简单例程

    首先,在 vs2008 环境下创建 MFC 运用程序 设置项目名称为 ComTest(这个地方随意命名,根据个人习惯),点击确定后,点击下一步 出现如下界面 选择"基于对话框"模式 ...

  10. C语言dsPIC / PIC24 serial bootloader和C#语言bootloader PC端串口通信程序

    了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). 新dsPIC/PIC2 ...

随机推荐

  1. [.net 面向对象编程基础] (15) 抽象类

    [.net 面向对象编程基础] (15) 抽象类 前面我们已经使用到了虚方法(使用 Virtual修饰符)和抽象类及抽象方法(使用abstract修饰符)我们在多态一节中说到要实现类成员的重写必须定义 ...

  2. 基于百度翻译API开发属于自己的翻译工具

    你是否每天使用着网页翻译工具?你是否遇到过这种情况,上网过程中遇到一个很长的单词但是又不能复制,要开两个浏览器,一个打开百度翻译,照着另一个网页输入单词?你安装了各种翻译软件后,又删除,只因忍受不了那 ...

  3. Ubuntu下解决adb devices:???????????? no permissions的方法

    之前一直都是在windows下进行开发的,但是这次由于一个小模块用的东西只能在linux下运行,所以就发生了这么一系列的问题环境:虚拟机Vmware下的Ubuntu12.10事件:连接android手 ...

  4. jQuery的动画处理总结

    最近一年多一直在做前端的东西,由于老板在追求一些年轻动感的效果,让页面元素不能仅仅是简单的隐藏显示,所以经常会使用一些动画效果,发现jQuery的动画真心好用啊,把常用的几个总结一下,希望不再每次使用 ...

  5. hammer.js手势库使用

    hammer.js是一款移动端手势库组件,支持pan(拖动).swipe(滑动).tap(轻触).press(按压,即长按).doubletap(双击)等很多手势操作,提供比较完善的事件监听机制,但是 ...

  6. C# 进制转换 (没有数值的长度限制)

    曾经在大学时做过一个c的进制转换算法,那时由于技术的局限性,数值的大小受到限制(系统数据类型长度限制),多年以后,自己那台学习机陈旧后感觉要报废了,整理了一下里面的东西,偶尔在一个角落里发现了这个转换 ...

  7. Java 线程 — ConcurrentHashMap

    ConcurrentHashMap ConcurrentHashMap 结构 采用了分段锁的方法提高COncurrentHashMap并发,一个map里面有一个Segment数组--即多个Segmen ...

  8. px 与 dp, sp换算公式?

    PPI = Pixels per inch,每英寸上的像素数,即 "像素密度" xhdpi: 2.0 hdpi: 1.5 mdpi: 1.0 (baseline) ldpi: 0. ...

  9. C#调用Couchbase中的Memcached缓存

    安装服务端 服务端下载地址:http://www.couchbase.com/download 选择适合自己的进行下载安装就可以了,我这里选择的是Win7 64. 服务端安装完后,如果成功了,那么在浏 ...

  10. Android基于mAppWidget实现手绘地图(九)–如何处理地图对象的touch事件

    为了响应touch事件,需要设置OnMapTouchListener 示例: private void initMapEventsListener() { mapWidget.setOnMapTouc ...