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

在做通信之前要先弄一个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. 解决Access连接 accdb 不可识别的数据库格式异常

    在Access07之前的数据库后缀名均为*.mdb 而连接字符串写成Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\myFolder\*.mdb ;Pe ...

  2. js执行过程

    正如我们了解的一样,当我们书写了JS程序之后,打开浏览器,我们的代码就可以开始运行了(当然保证你的代码没有问题,才能按照你的预期进行执行).刚才说的是JS执行的一个大的环境,今天我们学习一下,JS在解 ...

  3. EcShop二次开发系列教程–总纲

    EcShop作为老牌的B2C独立网店系统,功能非常全名,强大的文件.数据库缓存机制,保证前后台系统执行速度更快.系统平稳运行.但是过多的功能也或多或少的会影响到系统的整个效率,所有在使用EcShop搭 ...

  4. windows下编译lua源码

    所有的lua源码都放在了 src 文件夹下,当然,不同的lua版本目录结构有可能不一样,但是都会有 src 这个文件夹,只有这个才是我们编译必须的.而且lua越做越精简了,5.1的版本里面还有一些te ...

  5. c#写入Mysql中文显示乱码 解决方法

    如题,mysql字符集utf8,c#写入中文后,全部显示成?,一个汉字对应一个?解决方法:在数据库连接字符串中增加字符集的说明,Charset=utf8,如 MySQLConnection con = ...

  6. 获取枚举的title

    public class StringValue : System.Attribute { private readonly string _value; public StringValue(str ...

  7. linux的一点小随笔

    随意写的一些东西,也就为以后自己可能看看... 1.vim安装,sudo apt-get install vim-gtk,于是vim就安装好了.当然在我电脑上还出现了gvim,简单的vim配置(etc ...

  8. 【转载/修改】ScrollLayout代码修正,追加模仿viewpager滚动速度

    组件作用为类似ViewPager但直接插视图的横向滚动容器. 修改自:http://blog.csdn.net/yaoyeyzq/article/details/7571940 在该组件基础上修正了滚 ...

  9. 博客导出工具(C++实现,支持sina,csdn,自定义列表)

    操作系统:windowAll 编程工具:visual studio 2013 编程语言:VC++ 最近博文更新的较频繁,为了防止账号异常引起csdn博文丢失,所以花了点时间做了个小工具来导出博文,用做 ...

  10. oracle 约束

    约束是表中列的属性,用来维护数据结构完整性的一种手段约束的种类:NOT NULLUNIQUEPARIAMRY KEYFOREIGN KEYCHECK enble validate 检查现有数据和新数据 ...