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

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

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. ZOJ 1229 M-Gift?!

    https://vjudge.net/contest/67836#problem/M There is a beautiful river in a small village. N rocks ar ...

  2. Oracle查询字段中有空格的数据

    一.问题说明 最近在给某个用户下的表批量添加注释时,在程序中将注释名用trim()过滤一遍就可以了,但是在程序执行成功后怎么检测添加的注释名是否有空格存在呢? 二.解决方法 1.SELECT * FR ...

  3. 第45天:2017webstrom下载破解汉化

    1.webstrom 11.0.3下载地址1:http://pan.baidu.com/s/1kVQjcwf 密码:uggr 下载地址2:http://pan.baidu.com/s/1kVQjcwf ...

  4. CodeForces 632E Thief in a Shop

    题意:给你n种物品,每种无限个,问恰好取k个物品能组成哪些重量.n<=1000,k<=1000,每种物品的重量<=1000. 我们搞出选取一种物品时的生成函数,那么只要对这个生成函数 ...

  5. SP263 PERIOD - Period

    题目描述 For each prefix of a given string S with N characters (each character has an ASCII code between ...

  6. P3385 【模板】负环

    题目描述 暴力枚举/SPFA/Bellman-ford/奇怪的贪心/超神搜索 输入输出格式 输入格式: 第一行一个正整数T表示数据组数,对于每组数据: 第一行两个正整数N M,表示图有N个顶点,M条边 ...

  7. Django错误 OperationalError: no such column: xxx

    模型前后操作如下: 第一次迁移: class Snippet(models.Model): created = models.DateTimeField(auto_now_add=True) titl ...

  8. MySQL不支持远程连接的解决办法

    如果mysql不支持远程连接,会出现提示:错误代码是1130,ERROR 1130: Host * is not allowed to connect to this MySQL server ,解决 ...

  9. BZOJ5289 & 洛谷4437:[HNOI/AHOI2018]排列——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=5289 https://www.luogu.org/problemnew/show/P4437 考虑 ...

  10. 洛谷 P1640 [SCOI2010]连续攻击游戏 解题报告

    P1640 [SCOI2010]连续攻击游戏 题目描述 lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有2个属性,这些属性的值用[1,10000]之间的数表示.当他使用某种装备 ...