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

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

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. PokeCats开发者日志(九)

      现在是PokeCats游戏开发的第十五天的中午,总算过了规范性检查这一关. 但愿能过吧.

  2. Jenkins系列-Jenkins修改主目录步骤说明

    在使用Jenkins做持续集成过程中,在构建很多次后发现有时在构建的时候系统提示磁盘空间不足,此时检查发现Jenkins的主目录挂载区放在了服务器根目录下,占用空间较大,此时除了对服务器的磁盘进行扩容 ...

  3. BZOJ 1491 社交网络(最短路)

    对于这道题,如果我们能求出s到t的最短路径数目和s由v到t的最短路径数目,剩下的很好求了. 令dis[i][j]表示i到j的最短路径,dp[i][j]表示i到j的最短路径条数,如果dis[s][v]+ ...

  4. Socket_SSH-1

    服务器端: import socket,os server=socket.socket() server.bind(('localhost',9999)) server.listen() while ...

  5. hihoCoder#1838 : 鎕鎕鎕 贪心

    ---题面--- 题解: 神奇的贪心题,,,感觉每次做贪心题都无从下手... 我们首先按照a对所有卡片从小到大排序,然后从1开始,从连续的两张牌中取b最大的,最后一张单出来的也取了. 可以证明,这样的 ...

  6. POJ2749:Building roads——题解

    http://poj.org/problem?id=2749 (这个约翰的奶牛真多事…………………………) i表示u与s1连,i+n表示u与s2连. 老规矩,u到v表示取u必须取v. 那么对于互相打架 ...

  7. BZOJ [Ctsc2002] Award 颁奖典礼 解题报告

    [Ctsc2002] Award 颁奖典礼 Description IOI2002的颁奖典礼将在YONG-IN Hall隆重举行.人们在经历了充满梦幻的世界杯之后变得更加富于情趣.为了使颁奖典礼更具魅 ...

  8. UVA.10066 The Twin Towers (DP LCS)

    UVA.10066 The Twin Towers (DP LCS) 题意分析 有2座塔,分别由不同长度的石块组成.现在要求移走一些石块,使得这2座塔的高度相同,求高度最大是多少. 问题的实质可以转化 ...

  9. bzoj1263: [SCOI2006]整数划分(高精度+构造)

    第一次写压位高精度只好抄黄学长的 代码最后一段想了好久一看评论区才知道黄学长写错了= =很气 自己最后改对了T^T 这题最优是一直划分3出来直到<=4 #include<iostream& ...

  10. poco入门

    源码按照poco.然后看README,进行安装. ./configure make make install #include "Poco/ActiveMethod.h" #inc ...