gps(global position system)具有全球性、全天候性优势的定位、定时、测速系统,用户利用gps接收机接收卫星发射的信号,从而获取当前位置的大地坐标、高程和时间等信息,达到定位、导航或测量高程的目的。卫星导航定位技术被广泛应用于海洋勘测、海洋工程、海洋开发和军事作战中,高精度、快捷方便、全天候等优良特性,使其越来越受到人们的青睐。在gps导航中,需要实时采集遵循nmea0183协议的gps数据,对数据进行处理后,通过odbc接口将用户的位置、时间、速度等信息存到数据库,为以后在电子地图上实时显示目标位置提供依据。为了避免由于一直等待串口i/0操作而引起的线程阻塞,要求程序在对串行端口进行实时监控的同时,可以在前台进行数据提取、保存、显示等操作。为了解决实时性和多任务处理,避免某项任务长时间占用cpu,多线程编程是一个比较理想的选择。
1 多线程概述
1.1 基本概念
进程是程序在计算机上的一个执行实例,线程是程序中的一条执行分支,多线程就是在同一个程序中可以同时执行多个任务。每一个进程至少有一个主执行线程,它无需由用户去主动创建,是由系统自动创建的。用户根据需要在应用程序中创建其他线程,多个线程并发地运行于同一个进程中。
一个进程中的所有线程都在该进程的虚拟地址空间中,共同使用这些虚拟地址空间、全局变量和系统资源。
1.2 vc
vc++环境对多线程技术的支持visual c++6.0中,mfc类库提供了对多线程编程的支持,使得多线程编程更加方便。mfc中有两类线程,分别称之为工作者线程和用户界面线程。二者的主要区别在于工作者线程没有消息循环,而用户界面线程有自己的消息队列和消息循环。工作者线程通常用来执行后台计算和维护任务。用户界面线程一般用于处理独立于其他线程执行之外的用户输入,响应用户及系统所产生的事件和消息等。
1.3 线程创建、挂起、恢复、终止
在mfc中,一般用全局函数afxbeginthread()来创建并初始化一个线程的运行,该函数有两种重载形式,分别用于创建工作者线程和用户界面线程。sus-pendthread()和resumethread()分别用于挂起指定的线程和恢复用suspendthread()挂起的线程。exit-thread(dword dwexitc0de)用于线程终结自身的执行。
1.4 线程同步
线程之间经常要同时访问一些资源,因此对共享资源进行访问引起冲突是不可避免的。为了解决这种资源冲突问题,必须引入线程同步的概念。win32 api提供了多种同步控制对象来解决共享资源访问冲突,包括使用临界区、使用互斥对象、使用信号量、使用事件。
2 串口通信编程
目前,在windows下编程时,常用的串口通信主要有3种方法:用msc0mm通信控件;用windows api进行编程;使用第三方提供的一些串口通讯类进行编写。
(1)mscomm控件
利用mscomm控件会使编程快捷简单。然而,由于做了大量的封装,降低了编程的可控性和灵活性,因此在多线程多串口编程时,需要做许多复杂的处理。
(2)windows api
利用windows api编写串口程序,特别是复杂的多线程串口程序时,对于程序员的编程能力要求较高。除了需要程序员熟练掌握和使用众多的api函数,能编写很多底层代码之外,还必须熟悉线程的编程方法。
(3)第三方串口通信类
利用第三方的串口通信类进行串口编程时,既可以使编程效率高,程序可控性强,又比window api编程简单,其中应用最多的第三方的串口通信类是cserial-port。它基于多线程,是一个win32 api的打包类,对处理串口的win32 api类进行了封装,借助这个类可以很方便地对串口进行操作,容易实现多线程的串口通信,编写的程序在windows 98/nt/2000/xp操作系统下可很好地运行。
比较3种串口通信方式,可以发现使用第三方串口通信类cserialport是实现windows下多线程串口编程的较好选择。
3 多线程编程技术在gps数据采集系统中的应用
3.1 gps导航系统功能分析
gps导航是通过gps定位技术实时给出用户所在的位置,这就要求需要实时接收来自gps接收机串口的定位数据,在实时监视串口的同时还需要进行数据存储、显示等,利用多线程串口通信技术将很好地解决这个问题。通过对gps导航系统分析,将程序分成以下几个线程:
主线程:负责处理用户界面的消息处理,按照预定义流程调度其他线程处理数据。
串口监视线程:监视串口,采集数据并将数据保存到一个缓冲区。
入库线程:从缓冲区读取数据进行相应处理并将处理好的数据存入数据库。
显示线程:通过地图匹配算法将用户实时位置显示在电子地图上。
gps导航系统框图如图1所示。
3.2 具体实现
系统首先对线程在相应的头文件中说明,然后在程序初始化时加入创建程序代码,这样创建后,线程就可以和主线程并发执行了。主线程、入库线程、显示线程与一般的编程处理相同,所以下面着重说明串口监视线程。
对串口的操作采用基于多线程编程的cserialport类,其工作流程如下:首先设置好串口参数,再开启串口监测工作线程。串口监测工作线程监测到串口接收到的数据流、控制事件或其他串口事件后,就以消息方式通知主程序,激发消息处理函数进行数据处理,这是对接收数据而言的;发送数据可直接向串口发送。应用程序流程如图2所示。
编程步骤如下:
(1)建立程序
建立一个基于单文档的mfc应用程序cserial-porttest,其他步骤保持缺省状态。
(2)添加类文件
将serialport.h和serialport.cpp两个类文件复制到工程文件夹中,用project-add to project-files命令将上述两个文件加入工程,并在任何要调用这个类的模块中加上#include serialport.h文件。
在视类头文件中定义串口类的对象:cserialportm_port。
(3)人工增加串口消息响应函数oncommunica-tion(wparam ch,lparam port)
首先在cserialporttestview.h中添加串口字符接收消息wm_comm_rxchar(串口接收缓冲区内有一个字符)的响应函数声明,即:
在主线程初始化串口后创建commthread函数进入死循环,线程一直监视串口事件,当读串口事件发生,读取串口接收到的数据,向主线程发自定义消息wm_comm rxchar,通知主线程在相应的消息响应函数中进行数据处理,当收到主线程的写串口命令时,将缓存中的数据写到串口。
(5)在oncommunication()函数中进行数据处理每当串口接收缓冲区内有一个字符时,就产生一个wm comm rxchar消息,触发oncommunica—tion函数。这时就可以在函数中进行相应数据处理,提取出时间、经纬度、速度等定位的关键数据,然后将这些数据保存到数据库。
4 结 语
串行通讯在通讯领域被广泛应用。利用基于多线程的第三方串vi通信类cserialport很好地解决了由于串口长时间占用cpu而引起的线程堵塞等问题,编程简单、方便、可移植性强,对于其他类型的串口通信问题均可采用。该程序由microsoft visual c++6.0编译,在windows xp下运行通过。
变频器调试从正确设置参数开始
海信推出RFID食材管理冰箱,实现独特的1+1》2的技术优势
无人机在医疗领域的实际应用
IT资源投入持续加大,产品化进程提速
FPGA内实现按键消抖的方法
基于多线程编程技术在GPS接收机中的应用研究
新唐科技W79L632A主板简介
衡量自动驾驶的唯一标准 就是可商业化的能力
如何实现锂电池条码识别和文本对比
Redmi宣布Redmi K20系列用户可携带手机在附近小米之家免费领取手机壳
新品发布 | Semiware新推PLED系列LED开路保护器
TDK推出应用于工业控制领域高的新工艺传感器
LED灯光有恢复肌肉的功能有望治疗渐冻症等神经疾病患者的疾病
高通888/苹果A14/华为麒麟9000的区别对比分析
科学家跨越44公里成功实现高精度量子传送
肥料氮磷钾检测仪的特点有哪些
人工智能年度回顾及2020十大预测
等离子:从工作原理看其优势
恩智浦的i.MX 8M Plus应用处理器全方位赋能工业边缘智能应用
基于虚拟仪器编程软件实现多传感器信息采集平台的设计