C#--简单的串口通信程序
前几天做毕业设计,其中要用到串口和下位机进行通信,于是自己捣鼓了一个简单的串口通信程序。
在做通信之前要先弄一个SerialPort组件出来,当然也可以通过程序来创建。本次设计中采用的是拖的winform中提供的组件,效果是一样的。不过要使程序正确的运行起来,电脑上要安装一个pl232的驱动,安装完成后,还必须要插入一根串口线才行,或者是USB转串口的线也可以。
SerialPort有很多的属性和方法,但是在我做的这个简单的串口通信中用到的属性和方法很少,可以讲VS调出来看看有哪些属性和方法,有很多的属性已经帮我们设置好了,利用默认的设置就行
1、设置COM口
串口通信是需要利用计算机的COM接口,而很多的接口是被其它程序使用的,故首先要获得计算机当前我们程序中能够使用的COM接口,首先要添加一个引用:Microsoft.VisualBasic
<span style="font-size:18px;"> private string LoadSerial ()
{
Microsoft.VisualBasic.Devices.Computer pc;
pc = new Microsoft.VisualBasic.Devices.Computer();
//判断能够使用的COM口数量
if (pc.Ports.SerialPortNames.Count > 0)
{
//当有COM口可以使用的时候,将第一个COM口赋值给属性PortName
//也可以直接:serial.PortName = "COM2"; 指明了要使用COM2接口
serial.PortName = pc.Ports.SerialPortNames[0];
serial.BaudRate = 115200; //设置通信的波特率,默认的是9600,所以也可以不用设置
serial.StopBits = System.IO.Ports.StopBits.One; //停止位的位数,一般的串口通信都有停止位
serial.DateBit = 8; //数据位数,每一帧有效数据的位数,默认的为8,这个根据需要设置
}
else
{
return "系统没有可用串口,请检查和下位机连线是否正常";
}
return "OK";
}</span>
我设置的属性也基本上都是这些,其他的什么读缓存大小写缓存大小以及什么读取超时和写超时等等都使用默认的就OK,主要还是COM端口的设置
2、发送数据
串口通信,对方是下位机,故在通信中采用的是ASCII码,所以要先将数据转换成二进制然后进行发送,由于系统会自动的添加什么启示结束位等,我们也就不需要关系,直接将要发送的数据丢给他就行,当然也可以手动的进行判断。发送数据前需要先打开串口。
<span style="font-size:18px;"> try
{
if (!serial.IsOpen) //判断串口是否打开,会返回一个布尔值
{
serial.Open(); //如果串口没有打开就打开串口
}
byte[] by = ASCIIEncoding.ASCII.GetBytes("b"); //将要发送的数据转换成二进制
serial.Write(by, 0, by.Length); //发送
}
catch (Exception ex)
{
return "请求结束出错:" + ex.Message;
}</span>
因为要打开串口,串口是硬件资源,打开的时候很可能会失败抛异常,故用一个try...catch...语句包起来。发送数据的方法还有一个WriteLine,但个人觉得用Wrte更好。其实严格的讲,在发送之前应该先判断是否能够进行发送,这可以通过属性来完成,在这里就没有判断了,直接发送。
3、创建一个接收数据的后台线程
本次用串口来进行通信主要是用来接收数据,就收数据中没有采用系统提供的事件机制,而是创建了一个后台的线程来进行不断的监视读取缓存中有没有数据。先创建后台线程:
<span style="font-size:18px;"> private string LoadThread()
{
try
{ Thread thread = new Thread(ReceiveDate); //传递的是接收数据的方法,这个方法中用来接收数据
thread.Name = "serialThread";
thread.IsBackground = true;//设置线程为后台线程,前台关闭,此线程也就关闭
thread.Start();
}
catch (Exception ex)
{
return "出错了!" + ex.Message;
}
return "OK";
}</span>
4、数据的接收和处理
设计中事先约定好的通信协议就是:总共七位数据,第一位是ABCDE五个字符中任意一个,第二位是数字,第三位是小数点,第4~6位是数字,最后一位是字符V。
由于ASCII中得到的空格和换行符是用"\0"和“\n”来表示的,利用string.trim()方法是不能够将这个给移除的,所以每次都只是读取一位数据,当然这样肯定会影响通信的效率。读取一位数据后先判断是不是空格和换行,是就将数据丢弃,一般空格和换行都是出现在上一组数据发送完成后才有的,没有考虑数据出错后变为"\0"和"\n"的问题,这也算是一个漏洞。七位数据接收完成后,通过正则表达式来进行验证,验证通过后将数据存入到事先准备好的字典中,字典的关键字是七位数据中的第一位子字符串,值是一个字符串集合,用来将小数点去掉后四位数字组成的字符串存储下来。
代码如下:
<span style="font-size:18px;"> //声明一个字典,存放数据
Dictionary<string, List<string>> receiveDate = null;
private void ReceiveDate ()
{
string date = ""; //保存接收的数据
//实例化这个字典
receiveDate = new Dictionary<string, List<string>>();
string datePath = "";//用来存放,当前是那一路的信号
int index = 0; //七位数据,用来标识接收的是第几位数据
DateTime time1=DateTime.Now;
while (true)
{
try
{
if (serial.IsOpen) //如果串口打开就进行数据的读取
{
if (serial.BytesToRead > 0) //先判断读缓存中有没有数据
{
byte[] byteDate = new byte[1]; //设置每一次读取的字节数为1
serial.Read(byteDate, 0, byteDate.Length);
string strDate = ASCIIEncoding.ASCII.GetString(byteDate);
if (strDate == "\0" || strDate == "\n")
{
index = 0;
date = "";
continue;
}
else
{
index++; //接收的是多少位数
date += strDate;
}
if (index == 7) //七位数据接收完成
{
//利用正则表达式来进行匹配和数据的提取
Regex reg = new Regex(@"^([ABCDE]{1})(\d{1})\.(\d{3})V$");
Match match = reg.Match(date, 0, date.Length);
if (match.Success)
{
datePath = match.Groups[1].Value;
string numStr = match.Groups[2].Value + match.Groups[3].Value;
int num = -1;
//将接收到的数据进行一个转换,转换成功后保存
if (int.TryParse(numStr, out num))
{
//经过正则表达式验证后,datePath一定是ABCDE中的一个数据,先判断是否包含这个关键字,如果不包含就添加
if (!receiveDate.ContainsKey(datePath))
{
receiveDate[datePath] = new List<int>();//添加关键字就需要声明一个集合赋值给它
}
receiveDate[datePath].Add(num);//将数据存储起来
time = DateTime.Now; //记录正确接收数据的时间
}
}
//清空,进入下一轮的数据接收
date = "";
datePath = "";
index = 0;
}
}
else
{
<span style="white-space: pre;"> </span>//这个else中做的事情是如果长时间接收不到数据就添加0,代码就不附加了
}
}
}
catch (Exception ex)
{ }
}
}</span>
到此,一个简单的串口通信程序就搞定了。
C#--简单的串口通信程序的更多相关文章
- Qt编写串口通信程序全程图文解说
(说明:我们的编程环境是windows xp下,在Qt Creator中进行,假设在Linux下或直接用源代码编写,程序稍有不同,请自己修改.) 在Qt中并没有特定的串口控制类,如今大部分人使用的是第 ...
- 转:Qt编写串口通信程序全程图文讲解
转载:http://blog.csdn.net/yafeilinux/article/details/4717706 作者:yafeilinux (说明:我们的编程环境是windows xp下,在Q ...
- Qt编写串口通信程序全程图文讲解 .
在Qt中并没有特定的串口控制类,现在大部分人使用的是第三方写的qextserialport类,我们这里也是使用的该类.我们可以去 http://sourceforge.net/projects/qex ...
- 【转】Qt编写串口通信程序全程图文讲解
本文章原创于www.yafeilinux.com 转载请注明出处. (说明:我们的编程环境是windows xp下,在Qt Creator中进行,如果在Linux下或直接用源码编写,程序稍有不同,请自 ...
- C#中缓存的使用 ajax请求基于restFul的WebApi(post、get、delete、put) 让 .NET 更方便的导入导出 Excel .net core api +swagger(一个简单的入门demo 使用codefirst+mysql) C# 位运算详解 c# 交错数组 c# 数组协变 C# 添加Excel表单控件(Form Controls) C#串口通信程序
C#中缓存的使用 缓存的概念及优缺点在这里就不多做介绍,主要介绍一下使用的方法. 1.在ASP.NET中页面缓存的使用方法简单,只需要在aspx页的顶部加上一句声明即可: <%@ Outp ...
- 创建C#串口通信程序详解
在.NET平台下创建C#串口通信程序,.NET 2.0提供了串口通信的功能,其命名空间是System.IO.Ports.这个新的框架不但可以访问计算机上的串口,还可以和串口设备进行通信.我们将使用标准 ...
- C#串口通信程序详解
C#串口通信程序详解 摘要:创建C#串口通信程序需要注意什么呢?创建C#串口通信程序的步骤是什么?那么本文就向你详细介绍创建C#串口通信程序集体的内容. 在.NET平台下创建C#串口通信程序,.NET ...
- C语言PIC16 serial bootloader和C#语言bootloader PC端串口通信程序
了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). 新PIC16 Boot ...
- C#实现简单的串口通信
前言 本着学习研究的态度,用c#语言实现简单的串口通信工具. 一.串口通信原理 串口通信 串口通信(Serial Communications)的概念非常简单,串口按位(bit)发送和接收字节.尽管比 ...
随机推荐
- asp.net中分页与存储过程的一些总结
一.接上文,使用的是jquery AJAX 进行分页 分页存储过程代码如下: ALTER PROCEDURE [dbo].[USP_GetAlbumByPage] @pageIndex int,--当 ...
- WinForm程序安装、发布流程
一 签名 所谓签名就是给应用程序一个身份,申请一个专利.签名的时候需要选择证书.就向我们上学一样,得奖了老师给你发个证书.如果不进行签名,杀毒软件会把你打包后的exe文件作为病毒处理. 签名的步骤: ...
- AWS学习之EC2
1.AWS简介 AWS(Amazon Web Services )提供了一整套云计算服务,让您能够构建复杂.可扩展的应用程序.如今,成千上万各种规模的客户都在使用这些云计算服务,它们涉及各个行业,包括 ...
- JS 获取浏览器和屏幕宽高等信息代码
JS 获取浏览器和屏幕宽高等信息. 网页可见区域宽:document.body.clientWidth 网页可见区域高:document.body.clientHeight 网页可见区域宽:doc ...
- 倒水问题 (codevs 1226) 题解
[问题描述] 有两个无刻度标志的水壶,分别可装x升和y升 ( x,y 为整数且均不大于100)的水.设另有一水缸,可用来向水壶灌水或接从水壶中倒出的水, 两水壶间,水也可以相互倾倒.已知x升壶为空壶, ...
- FileUpload控件「批次上传 / 多档案同时上传」的范例--以「流水号」产生「变量名称」
原文出處 http://www.dotblogs.com.tw/mis2000lab/archive/2013/08/19/multiple_fileupload_asp_net_20130819. ...
- nandflash操作详解
1.nandflash就是嵌入式系统的硬盘 2.分类(1)MLC:存储单元格存储两位,慢,偏移,寿命短,容量大(2)SLC:存储一位.快,寿命长,容量小,昂贵 3访问:(1)独立编址,有专用的控制器, ...
- JSTL实现分页
JSTL(JSP Standard Tag Library ,JSP标准标签库)是一个不断完善的开放源代码的JSP标签库,是由apache的jakarta小组来维护的.JSTL只能运行在支持JSP1. ...
- C基础 那些年用过的奇巧淫技
引言 - 为寻一颗明星 为要寻一颗明星 徐志摩 1924年12月1日<晨报六周年纪念增刊> 我骑著一匹拐腿的瞎马, 向著黑夜里加鞭:—— 向著黑夜里加鞭, 我跨著一匹拐腿的瞎马.// 我冲 ...
- PAT乙级真题1001. 害死人不偿命的(3n+1)猜想 (15)(解题)
卡拉兹(Callatz)猜想: 对任何一个自然数n,如果它是偶数,那么把它砍掉一半:如果它是奇数,那么把(3n+1)砍掉一半.这样一直反复砍下去,最后一定在某一步得到n=1.卡拉兹在1950年的世界数 ...