张连环 曹竹梅
摘要:飞行模拟器具有可控性、经济性、可靠性等特点,也在飞行人员培训中大量使用。在VS.net环境下采用多串口卡和CSerialPort类编写的通信程序能够满足模拟器中上位机和多个下位机的实时通信要求,文章对其设计和实现方法进行了阐述。
关键词:串口扩展;多串口通信;VS.net;CserialPort
中图分类号:TP311文献标识码:A文章编号:1009-3044(2012)01-0026-02
The Design and Implementation of a Flight Simulator Multi-Serial Ports Communication
ZHANG Lian-huan1, CAO Zhu-mei2
(College of Information and Communication Engineering of Harbin Engineering University, Harbin 150056, China; 2. Naval Flying Academy, Huludao 125001, China)
Abstract: Flight Simulator has the characteristics of controllable, economy, reliability, etc, and is also widely used in flight personnel training. In VS.net environment, using multi-serial port card and communication program written by CSerialPort can meet upper position machine and many lower position machine communication requirement of real-time communication in simulator. The design and realization method are discussed in this paper.
Key words: serial port extension; multi-serial ports communication; VS.net; serialPort
飞行模拟器是一种能比较逼真地复现飞机在空中的飞行状态和环境的地面设备,是综合人的视觉、听觉信息、运动感觉信息的人在回路中的实时仿真系统。与真实飞机相比具有可控性、无破坏性、经济性、可靠性等特点。某型飞行模拟训练器系统中要求许多下位机同时跟一台上位机进行数据交换,以便能够及时采集各控制面板的开关、电位器状态和完成各仪表、显示设备的驱动,而计算机一般所能提供的串口数量有限,就需完成要对串口进行扩展和通过各串口进行数据交换的设计与实现。
1系统串口通信设计
32位下串口通信程序可以用多种方法实现:使用较多的有MSComm控件、Win32API通信函数、CSerialPort类。
MSComm是微软提供的串口编程控件,为应用程序提供串口通信功能,功能较完善,使用方便。
Windows API是所有Windows应用程序的根本。简单地说,API就是一系统的例程,应用程序通过调用这些例程来请求操作系统完成一些低级服务。调用Windows的API函数,可以清楚地掌握串口通信的机制,并且自由灵活。
CserialPort类是Remon Spekreijse写的一个串口类,是一个非常好用的多线程串口编程工具,它可以秀轻松的完成一般串口编程任务。
某型飞行模拟训练器系统中要求上位机同时和24个下位机通过串口进行数据交换,使用API函数实现串口编程,方法灵活、功能强大,但需要编程人员对串口硬件工作原理有较深入了解;使用MSComm控件编程简单,对付简单的任务完全可以胜任,但当需要在程序中用多个串口,且还要做很多复杂的处理,使用CserialPort类,很快就可搭好串口通信框架,编程者可以从烦心的框架编写中解脱出来,将精力放在通信协议的编制及数据处理上。
在本飞行训练系统中,硬件采用工业多串口卡进行串口扩展,软件基于VS.Net环境,采用CserialPort类进行串口通信程序的编写,基于RS-485标准来完成模拟训练器中多串口数据通信的功能。
2系统串口通信实现
2.1串口扩展
串口扩展在工控机上插三块PCI接口8口串口扩展卡,设置串口号为1~24,波特率设置为115200bps,与下位机一致。每个串口连接一特定设备。
2.2软件编程
CserialPort类是基于多线程的,其工作流程如下:
1)在dataChange工程中添加SerialPort类文件
将类文件SerialPort.h和SerialPort.cpp复制到工程所在文件夹中,在工程中添加类文件,并在dataChangeView.h中包含头文件:#include“SerialPort.h”
同时添加如下变量:
public:
CSerialPort m_serialPort[24]; //CSerailPort类对象
BOOL m_bSerialPortOpened[24]; //标志串口是否打开
BYTE inputBuff[24][12];//按Port口(0-24)接收数据
2)串口初始化
在OnInit函数中完成串口的初始化,
void dataChangeView::OnInit()
{
// TODO:在此添加控件通知处理程序代码
for(int i=0; i<24; i++)
if(m_serialPort[i].InitPort(this,i+1,115200,N,8,1,EV_RXFLAG | EV_RXCHAR,512)){
m_serialPort[i].StartMonitoring();//启动串口监视线程
m_bSerialPortOpened[i]=TRUE;
}
else
{
Cstring strTemp;
strTemp.Format(“COM%d没有发现,或被其它设备占用”,i+1);
AfxMessageBox(strTemp);
3)建立WM_COMM_RXCHAR的消息映射处理函数OnCommunication()完成数据的接收。LONG dataChangeView::OnCommunication(WPARAM ch, LPARAM port)
{…
Switch(port)
{
case 1:
device01DataReceive(ch,port);//串口1设备的数据接收breek;
…
case 24:
device24DataReceive(ch,port);//串口24设备的数据接收breek;
然后根据通信协议具体要求分别写出24个串口的数据接收函数
void dataChangeView:: device01DataReceive(WPARAM ch, LPARAM port)
…
void dataChangeView:: device24DataReceive(WPARAM ch, LPARAM port)
4)发送数据调用函数WriteToPort()直接向串口写数据即可,为保证上位机对下位机进行实时数据更新,添加WM_TIMER消息响应,每500ms向各串口定时发送数据。
void dataChangeView::OnTimer(UINT nIDEvent)
{
// TODO:在此添加消息处理程序代码和/或调用默认值
for(int i=0; i<24; i++)
{
if(m_bSerialPortOpened[i])
dataUpdatePort(i);
}
CFormView::OnTimer(nIDEvent);
}
对应的串口数据更新函数:
void dataChangeView::dataUpdatePort(int nPortNum)
{
Switch(nPortNum)
{
case 1:
char data[512];
int len=Str2Hex("…",data);
m_serialPort.WriteToPort(data,len);
break;
…
case 24:
…
Break;
}}
3结束语
本文分析了几种常用的实现串口通信的具体方法。最后通过串口卡扩展串口,软件在VS.net环境下使用CserialPort类编程基于RS-485标准进行上位机与各下位机进行数据通信。经测试,系统运行稳定,该方案可以在同类多串口通信系统中借鉴。
参考文献:
[1]孙鑫.VC++编程深入详解[M].北京:电子工业出版社,2006.
[2] [美]David J Kruglinski.Visual C++技术内幕[M].潘爱民,王国印,译.4版.北京:清华大学出版社,2009.
[3]侯俊杰.深入浅出MFC[M].2版.武汉:华中理工大学出版社,2001.
[4]龚建伟,熊光明.Visual C ++ /Turbo C串口通信编程实践[M].北京:电子工业出版社,2007.
[5]葛姣,高清维.基于RS-485的多机串口通信网络[J].安徽电子信息职业技术学院学报, 2009,10(6).