基于多线程方式的串行通信接口数据接收案例

广东职业技术技术学院  欧浩源

1、案例背景

在本博客的《【CC2530入门教程-06】CC2530的ADC工作原理与应用》中实现了电压数据采集的程序设计,传感器模块以每1秒发送一帧数据的形式通过串口向上位机发送电压数据。其数据帧由4个字节组成:一个帧头和一个帧尾,中间两个字节为电压数据,其格式如下:

帧头(0xAF)    电压数据高8位    电压数据低8位    帧尾(0xFA)

在篇博文中,将讲述如何通过多线程的方式,从串口接收传感器发送过来的数据帧,并将数据帧和换算后的实际电压值显示出来。

2、界面设计

3、引入命令空间

使用多线程的方式,需要引入命名空间:System.Threading;

使用串行通信接口,需要引入命名空间:System.IO.Ports;

4、初始化工作

首先,定义一个串行接口的对象和一个线程的字段,

然后,给主窗体添加窗体装载事件(即Load事件),在该事件中对各个控件的属性进行初始化工作。

        SerialPort com = new SerialPort();                  //实例化一个串口对象
Thread t; //定义一个线程字段
private void Form1_Load(object sender, EventArgs e)
{
textBox1.ReadOnly = true; //文本框只读
textBox1.ScrollBars = ScrollBars.Vertical; //文本框支持垂直滚动条
comboBox1.Items.Add("COM1");
comboBox1.Items.Add("COM2");
comboBox1.Items.Add("COM3");
comboBox1.Items.Add("COM4");
comboBox1.Items.Add("COM5");
comboBox1.SelectedIndex = ; comboBox2.Items.Add("");
comboBox2.Items.Add("");
comboBox2.Items.Add("");
comboBox2.Items.Add("");
comboBox2.Items.Add("");
comboBox2.SelectedIndex = ; comboBox3.Items.Add("");
comboBox3.Items.Add("");
comboBox3.Items.Add("");
comboBox3.SelectedIndex = ; comboBox4.Items.Add("");
comboBox4.Items.Add("1.5");
comboBox4.Items.Add("");
comboBox4.SelectedIndex = ;
}

5、设置串行接口

在进行串口通信的时候,一般的流程是:先设置通信的端口号波特率数据位停止位校验位,然后打开串口,接着发送数据和接收数据,最后要关闭串口

在本案例中,对串口的各个参数配置完成后,打开串口,然后启动串口数据接收的线程,开始以轮询的方式接收数据。

        private void button1_Click(object sender, EventArgs e)
{
if (button1.Text == "打开串口")
{
com.PortName = comboBox1.Text; //选择串口号
com.BaudRate = int.Parse(comboBox2.Text); //选择波特率
com.DataBits = int.Parse(comboBox3.Text); //选择数据位数
com.StopBits = (StopBits)int.Parse(comboBox4.Text); //选择停止位数
com.Parity = Parity.None; //选择是否奇偶校验 try
{
if (com.IsOpen) //判断该串口是否已打开
{
com.Close();
com.Open();
}
else
{
com.Open();
}
t = new Thread(com_DataReceived); //创建并启用数据接收线程
t.Start();
}
catch(Exception ex)
{
MessageBox.ReferenceEquals("错误:" + ex.Message, "串口通信");
}
button1.Text = "关闭串口";
}
else if (button1.Text == "关闭串口")
{
com.Close(); //关闭串口
t.Abort(); //终止线程
button1.Text = "打开串口";
}
}

6、串口数据接收线程方法

在该方法中,只有在串口打开并连接成功的情况下在去读取串口缓冲区中的数据。

首先通过读取BytesToRead属性,获取串口接收缓冲区中的数据字节数,然后根据这个属性实例化一个byte类型的数据,在通过Read方法将数据从缓冲区中读取到数组中。

将数据帧以十六进制的形式显示到窗体的文本框中。

通过计算获得实际的电压值,显示到对应的Lable标签中。

        private void com_DataReceived()
{
while (com.IsOpen) //在串口已打开情况下读取数据
{
string strRcv = "";
int count = com.BytesToRead; //获取串口缓冲器的字节数
byte[] readBuffer = new byte[count]; //实例化接收串口数据的数组
if (count != ) //如果串口接收到数据
{
strRcv = count.ToString() + " ";
com.Read(readBuffer, , count); //从串口缓冲区读出数据到数组
for (int i = ; i < readBuffer.Length; i++)
{
strRcv += readBuffer[i].ToString("X2") + " "; //16进制显示
}
textBox1.Text += strRcv + "\r\n"; if (readBuffer[] == 0xAF && readBuffer[] == 0xFA) //判断数据的帧头和帧尾
{
Int32 ad = readBuffer[];
double advalue;
ad <<= ;
ad |= readBuffer[]; //从数据帧中将电压数据取出
advalue = ad;
advalue = (advalue * 3.3) / ; //将数据换算为实际的电压值
label6.Text = advalue.ToString("F2") + " V";
}
}
Thread.Sleep();
}

7、程序运行结果

8、结语

串行接口通信是物联网技术应用中常用的数据交互方式。

利用多线程的手段以轮询的方式读取串口缓冲区的数据是一种最基础的方法,然而并不是唯一的方法。采用DadaReceived事件触发的方法来接收数据也很常用,当程序设计程度稍微复杂一点,后面再慢慢讲述。

【ALB学习笔记】基于多线程方式的串行通信接口数据接收案例的更多相关文章

  1. 【ALB技术笔记】基于多线程方式的串行通信接口数据接收案例

    基于多线程方式的串行通信接口数据接收案例 广东职业技术技术学院  欧浩源 1.案例背景 在本博客的<[CC2530入门教程-06]CC2530的ADC工作原理与应用>中实现了电压数据采集的 ...

  2. 【ALB学习笔记】基于事件触发方式的串行通信接口数据接收案例

    基于事件触发方式的串行通信接口数据接收案例 广东职业技术学院  欧浩源 一.案例背景 之前写过一篇<基于多线程方式的串行通信接口数据接收案例>的博文,讨论了采用轮询方式接收串口数据的情况. ...

  3. Mybatis进阶学习笔记——动态代理方式开发Dao接口、Dao层(推荐第二种)

    1.原始方法开发Dao Dao接口 package cn.sm1234.dao; import java.util.List; import cn.sm1234.domain.Customer; pu ...

  4. 孙鑫VC学习笔记:多线程编程

    孙鑫VC学习笔记:多线程编程 SkySeraph Dec 11st 2010  HQU Email:zgzhaobo@gmail.com    QQ:452728574 Latest Modified ...

  5. 【Spring学习笔记-MVC-3.1】SpringMVC返回Json数据-方式1-扩展

    <Spring学习笔记-MVC>系列文章,讲解返回json数据的文章共有3篇,分别为: [Spring学习笔记-MVC-3]SpringMVC返回Json数据-方式1:http://www ...

  6. Linux学习笔记——基于鸟哥的Linux私房菜

    Linux学习笔记--基于鸟哥的Linux私房菜 ***** ARM与嵌入式linux的入门建议 (1) 学习基本的裸机编程:ARM7或ARM9,理解硬件架构和控制原理 (这一步是绝对的根基) (2) ...

  7. JavaWeb和WebGIS学习笔记(三)——GeoServer 发布shp数据地图

    系列链接: Java web与web gis学习笔记(一)--Tomcat环境搭建 Java web与web gis学习笔记(二)--百度地图API调用 JavaWeb和WebGIS学习笔记(三)-- ...

  8. EF学习笔记(八):更新关联数据

    学习笔记主目录链接:ASP.NET MVC5 及 EF6 学习笔记 - (目录整理) 上一篇链接:EF学习笔记(七):读取关联数据 本篇原文链接:Updating Related Data 本篇主要考 ...

  9. 【EF6学习笔记】(八)更新关联数据

    上一篇链接:EF学习笔记(七):读取关联数据 本篇原文链接:Updating Related Data 本篇主要考虑对于有关联的数据进行新增.删除.更新操作:比如Course .Instructor: ...

随机推荐

  1. SQL 跨库查询

    使用SQL查询数据,不仅能查询当前库的数据,还可以跨数据库,甚至跨服务器查询. 下面给大家介绍一下跨服务器查询的步骤(以SQL Server为例): 1,建立数据库链接 EXEC sp_addlink ...

  2. 【Mysql】- Mysql 8.0正式版新亮点

    MySQL 8.0 正式版 8.0.11 已发布,官方表示 MySQL 8 要比 MySQL 5.7 快 2 倍,还带来了大量的改进和更快的性能! 注意:从 MySQL 5.7 升级到 MySQL 8 ...

  3. jconsole工具监控数据分析

    当Jconsole连接成功后,它从JMX获取信息,我们便可以在里面监控具体的内容.Jconsole能捕获到以下信息: 概述 - JVM概述和一些监控变量的信息 内存 - 内存的使用信息 线程 - 线程 ...

  4. 【bzoj1369】[Baltic2003]Gem 树形dp

    题目描述 给出一棵树,要求你为树上的结点标上权值,权值可以是任意的正整数 唯一的限制条件是相临的两个结点不能标上相同的权值,要求一种方案,使得整棵树的总价值最小. 输入 先给出一个数字N,代表树上有N ...

  5. OpenStack Queens版本Horizon定制化开发

    工具环境 1.VMware workstation 12+: 2.Ubuntu系统+Linux Pycharm: 3.OpenStack Queens版本Horizon代码: 问题及解决 1.项目代码 ...

  6. openstack之keystone部署

    前言 openstack更新频率是挺快的,每六个月更新一次(命名是是以A-Z的方式,Austin,Bexar...Newton).博主建议大家先可一种版本研究,等某一版本研究透彻了,在去研究新的版本. ...

  7. Python面向对象—类属性和实例属性

    属性:就是属于一个对象的数据或函数元素 类有类方法.实例方法.静态方法.类数据属性(类变量)和实例数据属性(实例变量). 类属性:包括类方法和类变量,可以通过类或实例来访问,只能通过类来修改. 实例属 ...

  8. React获取组件实例

    1. 直接new Component() 组件本身也是class,可以new,这样的组件实例意义不大 componentInstance = new Component(); 2. ReactDOM. ...

  9. 【初级算法】6. 两个数组的交集 II

    题目如下: 给定两个数组,写一个方法来计算它们的交集. 例如: 给定 nums1 = [, , , ], nums2 = [, ], 返回 [, ]. 注意: 输出结果中每个元素出现的次数,应与元素在 ...

  10. django项目初探

    一:创建django项目 设置数据库(默认sqlit3) mysql: setting:中设置 DATABASES = { 'default': { 'ENGINE': 'django.db.back ...