转自:吉翔的博客 http://jixiang1119.blog.163.com/blog/static/2827097320091283321941/
0 引言
随着计算机网络和多微机系统的广泛应用,接口通信技术日益成为当今一门非常重要的关键性技术。计算机与计算机以及其他设备的通信方式有串口通信,并口通信,USB通信和以太网通信等多种通信方式。尽管当今USB通信技术和以太网技术快速发展,然而串口通信技术始终以其连接简便,价格低廉,稳定可靠等优点,在计算机通信领域占有一席之地。MSComm控件是微软公司为了用户使用方便,而提供的一种便捷的控制串口编程的解决方案,本文将利用VC++平台详细介绍VC++下利用MSComm控件的串行通信方法。
1 VC++下MSComm控件的串口编程简介
1.1 MSComm控件串行通信处理方式
ActiveX是 Windows下进行应用程序开发的崭新技术,它的核心内容是组件对象模型 COM (Component Object Model),ActiveX控件包括一系列的属性、方法和事件 ,使用ActiveX控件的应用程序和 ActiveX控件之间的工作方式是客户/服务器方式,即应用程序通过 ActiveX控件提供的接口来访问 ActiveX控件的功能。Microsoft Communications Control (以下简称 MSComm)是 Microsoft 公司提供的简化 Windows 下串行通信编程的ActiveX控件 ,它为应用程序提供了通过串行接口收发数据的简便方法。程序员不需要花时间去了解复杂的API函数,只需要利用MSComm控件就可实现串口编程。
MSComm控件提供了两种处理通信问题的方法:一是事件驱动(Event-Driven)方法,二是查询法。
1) 事件驱动方式
事件驱动方式是处理串行端口交互作用的一种非常有效的方法。使用事件驱动法设计程序时 ,每当有新字符到达或端口状态改变 ,或发生错误时 ,MSComm 控件的OnComm事件捕获并处理这些通信事件。而应用程序在捕获该事件后,通过检查 MSComm 控件的 CommEvent 属性可以在OnComm事件处理函数中加入自己的处理代码,这种方法由于程序响应及时可靠,在实际生活中经常使用。
2) 查询方式
查询的实质实际上仍然是事件驱动,这种方法应用程序每当执行完某一串行口操作后,将不断的检查CommEvent属性的值来查询事件或错误,如果应用程序较小,而且是自保持的,那么这种方法可能比较可取。
1.2 MSComm 控件的属性
MSComm控件有许多属性,其中非常重要的几个属性如下:
CommPort :设置并返回通信端口号。
Setting:以字符串的形式设置并返回波特率,奇偶校验位,数据位,停止位。
PortOpen:设置并反返回通信端口的状态。也可以打开和关闭端口。
Input:从接收缓冲区返回和删除字符
Output:向传输缓冲区写一个字符
2 MSComm控件串口通信编程实例
2.1 创建串口通信程序工程MySCommTest
打开 Visual C + + 6. 0 集成开发环境 ,创建一个基于对话框的 MFC应用程序项目 ,命名为MySCommTest,完成这一步后 ,选择菜单项 Project/Add to Project/ Components and Controls,将弹出一个对话框,选择 “Registered ActiveX Controls” 文件夹下的 “Microsoft Communications Control,version6.0”,再点击“Insert”按钮为当前工程添加CMSComm类,并提示CMSComm类的头文件为MSComm.h,实现文件为MSComm.cpp。点击“ok”按钮,再点击“close”关闭对话框。这样就为当前工程添加了一个CMSComm类。同时在对话框编辑器里的工具栏将出现 MSComm 控件图标,形状类似电话机, 这就是MSComm 控件,要在对话框中应用该控件,还需要将该控件用鼠标拖入对话框中,这个对话框就成了MSComm控件的容器或者说是“宿主”。同时还要在对话框中添加的控件有:两个静态文本控件IDC_STATIC(其标签分别设为“发送数据”和“接收数据”),两个编辑框控件IDC_EDIT1和IDC_EDIT2,并分别为其添加成员变量m_strEditTXData和m_strEditRXData。变量类型为CString。一个按钮控件IDC_BUTTON1,其标签设为“发送”。
2.2 串口初始化
右键点击对话框,选择ClassWizard->Member Variables页,选中IDC_MSCOMM1控件,再点击“Add Variable…”在CMySCommTestDlg类中为串口控件添加CMSComm类的控制变量m_ctrlcomm。
在MySCommTestDlg::OnInitDialog( )函数中写入对串口的初始化语句。通过串口初始化变量m_ctrlcomm来设置串口控件的属性。
初始化代码示例如下:
BOOL CMySCommTestDlg::OnInitDialog( )
{
。。。。
//
m_ctrlcomm.SetCommPort(1); //选择com1
//波特率9600,无校验,8个数据位,1个停止位
m_ctrlcomm.SetInputMode(1); //1表示输入方式为二进制输入方式,0代表文本方式
m_ctrlcomm.SetInBufferSize(1024); // 设置输入缓冲区大小
m_ctrlcomm.SetOutBufferSize(512); // 设置输出缓冲区大小
//波特率9600,无校验,8个数据位,1个停止位
m_ctrlcomm.SetSettings("9600,n,8,1");
if(!m_ctrlcomm.GetPortOpen())
m_ctrlcomm.SetPortOpen(TRUE); //打开端口
m_ctrlcomm.SetRThreshold(1); //1表示每当串口接收缓冲区中多余或等于一个字符时将触发OnComm事件
m_ctrlcomm.SetInputLen(0); //设置当前接收区数据长度为0
m_ctrlcomm.GetInput(); // 先预读缓冲区以清除残留数据
return TRUE; // return TRUE unless you set the focus to a control
}
2.3 串口事件处理函数OnComm( )
MsComm控件一般用事件驱动方式从串口接收数据,事件驱动法完成对数据的监视和处理,有事件发生时或者出错时通知应用程序,并在程序中捕捉并处理这些事件。
右击对话框打开ClassWizard->Member Variables页,选中IDC_MSCOMM1控件,然后在Message中双击OnComm,为串口事件添加OnComm()消息处理函数。消息处理函数试对串口事件的处理,根据自身需要编写,本例的消息处理函数OnComm()主要是从串口接收数据并显示在接收数据编辑框中。
示例代码为:
void CMySCommTestDlg::OnComm() //使用MSComm控件的事件驱动方式接收串口数据
{
// TODO: Add your control notification handler code here
VARIANT variant_inp;
COleSafeArray safearray_inp;
LONG len,k;
CString strtemp;
BYTE rxdata[2048]; //设置BYTE数组
if( m_ctrlcomm.GetCommEvent()==2) //事件值为2表示接收缓冲区内有字符
{ variant_inp=m_ctrlcomm.GetInput(); //读缓冲区
safearray_inp=variant_inp; //VARIANT变量转化为COleSafeArray变量
len=safearray_inp.GetOneDimSize(); //得到有效的数据长度
for( k=0;k<len;k++)
{
safearray_inp.GetElement(&k,rxdata+k); //转换成BYTE型数组
}
for( k=0;k<len;k++) //将数组转换成Cstring型的变量
{ BYTE bt=*(char*)(rxdata+k); //字符型
strtemp.Format("%c",bt); //将字符送入临时变量
m_strEditRXData+=strtemp; //加入接收编辑框对应字符串
}
} UpdateData(FALSE); //更新编辑框内容
}
2.4 串口读写操作
在串口数据的发送和就收过程中都是使用的VARIANT数据类型,因此我们必须把CString字符串数据转换成variant数据进行串口数据传送。
同样的方法为按钮IDC_BUTTON1添加处理函数BIN_CLICKED,并在函数中添加如下处理代码:
void CMySCommTestDlg::OnButton1() //把CString字符串类型数据强制转换为variant类型数据从串口发送
{
// TODO: Add your control notification handler code here
UpdateData(TRUE); //读取编辑框内容
m_ctrlcomm.SetOutput(COleVariant(m_strEditTXData)); //发送数据
}
2.5 关闭串口
串口在进行数据处理完毕后,要关闭串口以释放串口,即将PortOpen()的属性设置为FALSE。至此一个完整的串口通信程序完成了。并经过串口调试助手测试,程序顺利运行。可以用文件的方法保存接收框的数据。添加一个“保存”按钮,为按钮添加单击事件,事件名为OnSave用以保存接收数据
void CSCommTestDlg::OnSave()
{ FILE *fp;
if((fp=fopen("data.txt","w+"))==NULL)
exit(0);
fprintf(fp,m_strEditRXData);
fclose(fp);
}
3 结束语
本文详细介绍了VC++下的MSComm控件编程方法,通过MSComm控件用户可以十分便捷的写出灵活性高,移植性强的串口通信程序,避免了去了解一些复杂的windows API函数。这种方法具有很强的实用性,可以广泛的用于工业数据采集等领域。