前几天做毕业设计,其中要用到串口和下位机进行通信,于是自己捣鼓了一个简单的串口通信程序。

在做通信之前要先弄一个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#--简单的串口通信程序的更多相关文章

  1. Qt编写串口通信程序全程图文解说

    (说明:我们的编程环境是windows xp下,在Qt Creator中进行,假设在Linux下或直接用源代码编写,程序稍有不同,请自己修改.) 在Qt中并没有特定的串口控制类,如今大部分人使用的是第 ...

  2. 转:Qt编写串口通信程序全程图文讲解

    转载:http://blog.csdn.net/yafeilinux/article/details/4717706  作者:yafeilinux (说明:我们的编程环境是windows xp下,在Q ...

  3. Qt编写串口通信程序全程图文讲解 .

    在Qt中并没有特定的串口控制类,现在大部分人使用的是第三方写的qextserialport类,我们这里也是使用的该类.我们可以去 http://sourceforge.net/projects/qex ...

  4. 【转】Qt编写串口通信程序全程图文讲解

    本文章原创于www.yafeilinux.com 转载请注明出处. (说明:我们的编程环境是windows xp下,在Qt Creator中进行,如果在Linux下或直接用源码编写,程序稍有不同,请自 ...

  5. 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 ...

  6. 创建C#串口通信程序详解

    在.NET平台下创建C#串口通信程序,.NET 2.0提供了串口通信的功能,其命名空间是System.IO.Ports.这个新的框架不但可以访问计算机上的串口,还可以和串口设备进行通信.我们将使用标准 ...

  7. C#串口通信程序详解

    C#串口通信程序详解 摘要:创建C#串口通信程序需要注意什么呢?创建C#串口通信程序的步骤是什么?那么本文就向你详细介绍创建C#串口通信程序集体的内容. 在.NET平台下创建C#串口通信程序,.NET ...

  8. C语言PIC16 serial bootloader和C#语言bootloader PC端串口通信程序

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

  9. C#实现简单的串口通信

    前言 本着学习研究的态度,用c#语言实现简单的串口通信工具. 一.串口通信原理 串口通信 串口通信(Serial Communications)的概念非常简单,串口按位(bit)发送和接收字节.尽管比 ...

随机推荐

  1. Data Mover Script Templates

    Datamover is probably the best way to export and import data between PeopleSoft databases and the sc ...

  2. JS获取网页属性包括宽、高等

    JS获取网页属性包括宽.高等. function getInfo()  { // www.jbxue.com var s = "";  s += " 网页可见区域宽:&q ...

  3. phpcms v9 中get的mysql查询表某字段最大值数据,表某字段不重复数据

    直切正题 1.表tb中字段num最大的数据 {pc:get $sql="select * from tb where num=(select MAX(num) from tb)"} ...

  4. Android Material Design:基于CoordinatorLayout实现向上滚动导航条ToolBar滚出、向下滚动导航条滚出

    activity_main.xml: <android.support.design.widget.CoordinatorLayout xmlns:android="http://sc ...

  5. SQL Server 基础之《学生表-教师表-课程表-选课表》

    一.数据库表结构及数据 建表 CREATE TABLE Student ( S# INT, Sname ), Sage INT, Ssex ) ) CREATE TABLE Course ( C# I ...

  6. mvc url路由参数的加密和解密

    查看某个信息的时候一般会在url上加上该信息在数据库中对应的主键id(而且一般是自增的) url是这样子的 xxxDetail/1 , 虽然对于我们开发人员来说可以这种显式的数据库主键会方便调试过程, ...

  7. Linux之kernal分析与启动20160610

    说一下LINUX内核的分析与启动: 一. 内核启动流程,据此配置内核(机器ID) 1.1 修改Makefile 1.2 选择默认配置 : make s3c2410_defconfig 1.3 make ...

  8. java 复习

    整型: byte 1 short 2 int 4 long 80b1001 1_233_32 1341414141414Ljava 没有无符号类型浮点型:float 4 double 812.2f 无 ...

  9. oracle group 语句探究(笔记)

    1.group by语句在oracle中没有排序功能,必须依靠order by才能实现按照预定结果的排序 2.group by 的cube扩展 with test as ( id, name from ...

  10. core java 5~6(OOP & 高级语言特征)

    MODULE 5 OOP 面向对象程序设计--------------------------------------------------------Object Oriented Program ...