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

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

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. 基于CarbonData的电信时空大数据探索

    摘要:作为IOT最底层的无线通信网络生成大量与位置相关的数据,用于无线通信网络规划和优化,帮助电信运营商建设更好体验的精品网络,构建万物互联的信息社会. 本文分享自华为云社区<基于CarbonD ...

  5. WCF学习笔记(基于REST规则方式)

    一.WCF的定义 WCF是.NET 3.0后开始引入的新技术,意为基于windows平台的通讯服务. 首先在学习WCF之前,我们也知道他其实是加强版的一个面向服务(SOA)的框架技术. 如果熟悉Web ...

  6. 技术实战:基于 MHA 方式实现 MySQL 的高可用(转)

    转自:http://os.51cto.com/art/201307/401702_all.htm MHA故障转移可以很好的帮我们解决从库数据的一致性问题,同时最大化挽回故障发生后的数据.本文分享了基于 ...

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

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

  8. Java精选笔记_多线程(创建、生命周期及状态转换、调度、同步、通信)

    线程概述 在应用程序中,不同的程序块是可以同时运行的,这种多个程序块同时运行的现象被称作并发执行. 多线程可以使程序在同一时间内完成很多操作. 多线程就是指一个应用程序中有多条并发执行的线索,每条线索 ...

  9. IPV6技术笔记(剖析IPv4toIPv6)

    IPV6技术笔记 IPv6地址入门概念 什么是IPv6? IPv6,全称Internet Protocol version 6,即网际协议版本6,也叫互联网通信协议第六版.是互联网工程任务组(IETF ...

随机推荐

  1. 多线程编程-- part 3 多线程同步->synchronized关键字

    多线程同时访问一个资源,可以会产生不可预料的结果,所以为这个资源加锁,访问资源的第一个线程为其加锁后,其他线程便不能在使用那个资源,直到锁被解除. 举个例子: 存款1000元,能取出800的时候我就取 ...

  2. SmartCoder每日站立会议 01

    1.站立会议内容 确定今天团队成员各自的任务,并讨论今后各自的学习方向. 站立会议照片: 2.任务看板: 3.燃尽图:

  3. java中File类应用:遍历文件夹下所有文件

    练习: 要求指定文件夹下的所有文件,包括子文件夹下的文件 代码: package 遍历文件夹所有文件; import java.io.File; public class Test { public ...

  4. Chrome 开发者工具断点调试(视频教程)

    很多人不了解 Chrome Dev Tools (开发者工具)的使用方法和技巧. 其中很多技能,无论是前端开发从业者,还是普通用户,了解一些还是对日常很有帮助的. 本猿定期录制.甚至根据您的需求来订制 ...

  5. wpf XAML xaml 进行 数据绑定,Resource DataContext ElementName

    先做个声明:这里绑定都在前台实现,至于后台怎么写,那比前台简单多了,但更常用的是xaml中绑定.我们分析下最简单的字符串绑定来弄清楚原理,其他的类推就是. 数据绑定主要是要弄清楚两个东西,一个是源So ...

  6. 简单vue项目脚手架(vue+webpack2.0+vuex+vue-router)

    github地址 使用技术栈 webpack(^2.6.1) webpack-dev-server(^2.4.5) vue(^2.3.3) vuex(^2.3.1) vue-router(^2.5.3 ...

  7. 隐马尔科夫模型HMM(三)鲍姆-韦尔奇算法求解HMM参数

    隐马尔科夫模型HMM(一)HMM模型 隐马尔科夫模型HMM(二)前向后向算法评估观察序列概率 隐马尔科夫模型HMM(三)鲍姆-韦尔奇算法求解HMM参数(TODO) 隐马尔科夫模型HMM(四)维特比算法 ...

  8. Azure 基础:Blob Storage

    Azure Storage 是微软 Azure 云提供的云端存储解决方案,当前支持的存储类型有 Blob.Queue.File 和 Table. 笔者在前文中介绍了 Table Storage 的基本 ...

  9. iOS bug调试技巧学习----breakpoint&condition

    给断点添加条件 - (void)testCondition2 { NSArray *array = @[@"我们", @"一起", @"来" ...

  10. 匿名属性 anonymous property

    利用匿名属性可以用很简洁的语法来自动声明不可变(immutable)的元组(tuple)类型. 属性:在字段用来表示类型和对象的状态的前提下,希望状态不被随意的更改,字段一般应该设置为private, ...