基于MSComm控件的串行异步通信程序设计.docx
《基于MSComm控件的串行异步通信程序设计.docx》由会员分享,可在线阅读,更多相关《基于MSComm控件的串行异步通信程序设计.docx(32页珍藏版)》请在冰豆网上搜索。
![基于MSComm控件的串行异步通信程序设计.docx](https://file1.bdocx.com/fileroot1/2023-2/9/358ddc04-8351-45ff-bd2c-90886ae5bcf1/358ddc04-8351-45ff-bd2c-90886ae5bcf11.gif)
基于MSComm控件的串行异步通信程序设计
*******************
实践教学
*******************
兰州理工大学
计算机与通信学院
2015年秋季学期
计算机通信课程设计
题目:
基于MSComm控件的串行异步通信程序设计
专业班级:
姓名:
学号:
指导教师:
王惠琴
成绩:
中文摘要
计算机与外部设备之间的通信方式有两种,一种是并行通信,另一种是串行通信。
由于串行接口简单、使用方便,从而使得异步串行通信成为计算机之间极为常用的通信手段。
我们的课程设计就是以串行通信为要求实施的,我在MicrosoftVisualC++6.0平台下,利用MSComm控件编写串口通信程序来实现异步传输,由于电脑上com端口只有一个,我就从网上下载了一个串口大师,虚拟了com2端口进行传输,实现串口通信。
此次设计以MFC来设计界面编制程序,同时利用MSComm控件以及程序运行,实现串口发送和接收功能。
关键字:
串行通信、MSComm控件、MicrosoftVisualC++6.0
目录
前言1
一、串行传输2
1.1基本概念2
1.2.传输模式3
1.3异步传输与同步传输3
二、RS-232接口标准5
2.1RS-232接口基本介绍5
2.2RS-232的通行方式6
三、系统分析7
3.1需求分析7
3.2系统分析7
四、详细程序设计及调试9
4.1程序设计9
4.2程序调试12
五、心得体会14
参考文献15
附录:
源程序16
前言
在通信领域内,有两种数据通信方式:
并行通信和串行通信。
随着计算机网络化和微机分级分布式应用系统的发展,通信的功能越来越重要。
通信是指计算机与外界的信息传输,既包括计算机与计算机之间的传输,也包括计算机与外部设备,如终端、打印机和磁盘等设备之间的传输。
随着通信技术和计算机网络技术的发展、Internet网的普及,计算机远程通信已渗透到国民经济的各个领域,在数据通信中,通常将待传送的每个字符的二进制代码按照由低位到高位的顺序依次发送的方式成为串行通信。
由于串行通信只需在发送方和接收方之间建立一条通信信道,因此可以减小通信系统的造价。
在远程通信中,一般采用串行通信的方式,由于串行接口简单、使用方便,从而使得异步串行通信成为计算机之间极为常用的通信手段。
而Windows以其多任务,事件驱动和高级的图形用户界面(GUI)等特点得到广泛应用,所以Windows环境下通信程序的设计成为一个关键问题。
由于VC6.0开发平台提供了良好的可视化开发环境,而且是目前开发Windows应用程序的强大、高效的开发平台之一,通过这次课程设计,培养和提高我的综合设计能力,为今后的学习和工作积累经验。
一、串行传输
1.1基本概念
串行通信是指通信的发送方和接收方之间数据信息的传输是在单根数据线上,以每次一个二进制的0、1为最小单位逐位进行传输。
串行数据传送的特点是:
数据传送按位顺序进行,最少只需要一根传输线即可完成,节省传输线。
与并行通信相比,串行通信还有较为显著的优点:
传输距离长,可以从几米到几千米;在长距离内串行数据传送速率会比并行数据传送速率快;串行通信的通信时钟频率容易提高;串行通信的抗干扰能力十分强,其信号间的互相干扰完全可以忽略。
但是串行通信传送速度比并行通信慢得多,并行通信时间为T,则串行时间为NT。
正是由于串行通信的接线少、成本低,因此它在数据采集和控制系统中得到了广泛的应用,产品也多种多样。
串口通信最重要的参数是波特率、数据位、停止位和奇偶校验。
(1)波特率:
实际上就是传输速度,它表示每秒钟传送的bit的个数。
当我们提到时钟周期时,我们就是指波特率。
波特率可以远远大于这些值,但是波特率和距离成反比。
(2)数据位:
这是衡量通信中实际数据位的参数。
当计算机发送一个信息包,实际的数据不会是8位的,标准的值是5、7和8位。
如何设置取决于你想传送的信息。
比如,标准的ASCII码是0~127(7位)。
扩展的ASCII码是0~255(8位)。
如果数据使用简单的文本(标准ASCII码),那么每个数据包使用7位数据。
每个包是指一个字节,包括开始/停止位,数据位和奇偶校验位。
由于实际数据位取决于通信协议的选取,术语“包”指任何通信的情况。
(3)停止位:
用于表示单个包的最后一位。
典型的值为1,1.5和2位。
由于数据是在传输线上定时的,并且每一个设备有其自己的时钟,很可能在通信中两台设备间出现了小小的不同步。
因此停止位不仅仅是表示传输的结束,并且提供计算机校正时钟同步的机会。
适用于停止位的位数越多,不同时钟同步的容忍程度越大,但是数据传输率同时也越慢。
(4)奇偶校验位:
在串口通信中一种简单的检错方式。
有四种检错方式:
偶、奇、高和低。
当然没有校验位也是可以的。
对于偶和奇校验的情况,串口会设置校验位(数据位后面的一位),用一个值确保传输的数据有偶个或者奇个逻辑高位。
例如,如果数据是011,那么对于偶校验,校验位为0,保证逻辑高的位数是偶数个。
如果是奇校验,校验位位1,这样就有3个逻辑高位。
高位和低位不真正的检查数据,简单置位逻辑高或者逻辑低校验。
这样使得接收设备能够知道一个位的状态,有机会判断是否有噪声干扰了通信或者是否传输和接收数据是否不同步。
1.2.传输模式
通过单线传输信息是串行数据通信的基础。
数据通常是在两个站(点对点)之间进行传送,按照数据流的方向可分成3种传送模式:
单工、半双工和全双工。
(1)单工形式
单工形式的数据传送是单向的。
通信双方中,一方固定为发送端,另一方则固定为接收端。
信息只能沿一个方向传送,使用一根传输线。
(2)半双工形式
半双工方式允许数据在两个方向上传输,但在某一时刻数据只允许在一个方向上传输。
中每端需有一个收/发切换电子开关,通过切换来决定数据向哪个方向传输。
因为有切换,所以会产生时间延迟,信息传输效率低些。
但是对于像打印机这样单方向传输的外围设备,用半双工方式就能满足要求了,不必采用全双工方式,可节省一根传输线。
(3)全双工形式
全双工数据通信分别由两根可以在两个不同的站点同时发送和接收的传输线进行传送,通信双方都能在同一时刻进行发送和接收操作。
在全双工方式中,每一端都有发送器和接收器,有两条传送线,可在交互式应用和远程监控系统中使用,信息传输效率较高。
1.3异步传输与同步传输
串行传输中,数据是一位一位按照到达的顺序依次传输的,每位数据的发送和接收都需要时钟来控制。
发送端通过发送时钟确定数据位的开始和结束,接收端需要在适当的时间间隔对数据流进行采样来正确地识别数据。
接收端和发送端必须保持步调一致,否则就会在数据传输中出现差错。
为了解决以上问题,串行传输可采用以下两种方法:
异步传输和同步传输。
(1)异步传输。
在异步传输方式中,字符是数据传输单位。
在通信的数据流中,字符间异步,字符内部各位同步。
异步通信方式的“异步”主要体现在字符与字符之间通信没有严格的定时要求。
异步传输中,字符可以是连续地、一个个地发送,也可以是不连续地、随机地进行单独发送。
在一个字符格式的停止位之后,立即发送下一个字符的起始位,开始一个新的字符的传输,这叫做连续的串行数据发送,即帧与帧之间是连续的。
断续的串行数据传送是指在一帧结束之后维持数据线的“空闲”状态,新的起始位可在任何时刻开始。
一旦传送开始,组成这个字符的各个数据位将被连续发送,并且每个数据位持续的时间是相等的。
接收端根据这个特点与数据发送端保持同步,从而正确地恢复数据。
收/发双方则以预先约定的传输速率,在时钟的作用下,传送这个字符中的每一位。
(2)同步传输。
在同步传输方式中,比特块以稳定的比特流的形式传输,数据被封装成更大的传输单位,称为帧。
每个帧中含有多个字符代码,而且字符代码与字符代码之间没有间隙以及起始位和停止位。
和异步传输相比,数据传输单位的加长容易引起时钟漂移。
为了保证接收端能够正确地区分数据流中的每个数据位,收发双方必须通过某种方法建立起同步的时钟。
可以在发送器和接收器之间提供一条独立的时钟线路,由线路的一端(发送器或者接收器)定期地在每个比特时间中向线路发送一个短脉冲信号,另一端则将这些有规律的脉冲作为时钟。
这种技术在短距离传输时表现良好,但在长距离传输中,定时脉冲可能会和信息信号一样受到破坏,从而出现定时误差。
另一种方法是通过采用嵌有时钟信息的数据编码位向接收端提供同步信息。
二、RS-232接口标准
2.1RS-232接口基本介绍
RS-232是使用最早、应用最多的一种异步串行通信总线,它是美国电子工业协会1962年公布的,1969年最后一次修订而成。
后面有于1987年和1991年进行修订。
其中232是该标准的标志。
RS-232主要用来定义计算机系统的一些数据终端(DTE)和数据电路端接设备(DCE)之间的电气特性,如CRT、打印机(串行)、扫描仪等与CPU的通信大都采用RS-232总线,单片机仿真器也都采用这种通信接口。
因此,RS-232是目前应用最广泛的一种串行标准总线。
功能特性是指它的每一个引脚的名称及功能,并说明相互间的操作关系。
在25芯的连接器中,仅对20条线作了规定,剩下的5条线未作规定,其中9、10脚为测试保留,11、18和25脚未指定。
这些信号分为两类,一类是DTE与DTE交换的信息:
TxD和RxD;另一类是为了正确无误地传输上述信息而设计的联络信号。
下面就介绍RS-232部分针脚的功能:
:
传送数据:
TxD(管脚2):
发送数据,由发送终端(DTE)向接收端(DCE)发送的信息,按先低位后高位的顺序发出。
RxD(管脚3):
接受数据,用来接收DTE发送端(或调制解调器)输出的数据。
联络握手:
RTS(管脚4):
请求传送信号,这是DTE向DCE发出的联络信号,当RTS=1时,表示DTE请求向DCE发送数据。
CTS(管脚5):
允许发送,这是DCE向DTE发出的联络信号。
当CTS=1,时,表示本地DCE响应DTE向DCE发出的RTS信号,且本地DCE准备向远程DCE发送数据。
DSR(管脚6):
数据准备就绪,这是DCE向DTE发出的联络信号。
DSR将指出本地DCE的工作状态。
当DSR=1时,表示DCE没有处于测试通话状态,这时DCE可以与远程DCE简历通道。
DCD(管脚8):
数据载波检测,这是DCE向DTE发出的状态信息,当DCD=1时,表示本地DCE收到远程DCE发来的载波信号。
DTR(管脚7):
数据终端就绪,这是DTE向DCE发出的联络信号,DTR=1时,表示DTE处于就绪状态,本地DCE和远程DCE之间建立通信通道,而DTR=0时,将迫使DCE终止通信工作。
RI(管脚22):
铃声指示,这是DCE向DTE发出的状态信息。
RI=1时,表示本地DCE收到远程DCE振铃信号。
2.2RS-232的通行方式
RS-232通行方式允许简单连接三线:
Tx、Rx和地线。
但是对于数据传输,双方必须对数据定时采用使用相同的波特率。
尽管这种方法对于大多数应用已经足够,但是对于接收方过载的情况这种使用受到限制,这时需要串口的握手功能。
在这一部分,我们讨论三种最常用的RS-232握手形式:
软件握手、硬件握手和Xmodem。
(1)软件握手:
我们讨论的第一种握手是软件握手。
通常用在实际数据是控制字符的情况,类似于GPIB使用命令字符串的方式。
必须的线仍然是三根:
Tx,Rx和地线,因为控制字符在传输线上和普通字符没有区别,函数SetXModem允许用户使能或者禁止用户使用两个控制字符XON和OXFF。
这些字符在通信中由接收方发送,使发送方暂停。
(2)硬件握手:
第二种是使用硬件线握手。
和Tx和Rx线一样,RTS/CTS和DTR/DSR一起工作,一个作为输出,另一个作为输入。
第一组线是RTS(RequesttoSend)和CTS(CleartoSend)。
当接收方准备好接收数据,它置高RTS线表示它准备好了,如果发送方也就绪,它置高CTS,表示它即将发送数据。
另一组线是DTR(DataTerminalReady)和DSR(DataSetReady)。
这些现主要用于Modem通信。
使得串口和Modem通信他们的状态。
例如:
当Modem已经准备好接收来自PC的数据,它置高DTR线,表示和电话线的连接已经建立。
读取DSR线置高,PC机开始发送数据。
一个简单的规则是DTR/DSR用于表示系统通信就绪,而RTS/CTS用于单个数据包的传输。
(3)XModem握手:
最后讨论的握手叫做XModem文件传输协议。
这个协议在Modem通信中非常通用。
尽管它通常使用在Modem通信中,XModem协议能够直接在其他遵循这个协议的设备通信中使用。
在LabWindows中,实际的XModem应用对用户隐藏了。
只要PC和其他设备使用XModem协议,在文件传输中就使用LabWindows的XModem函数。
函数是XModemConfig,XModemSend和XModemReceive。
三、系统分析
3.1需求分析
在本次课程设计中,我们的题目是基于MSCommon控件的异步串口通信程序设计,是在MicrosoftCommunicationsControl6.0开发工具的平台之下,利用MSComm控件完成PC机间的串口通信。
在此开始之前,要考量这次设计的需求,我觉得应该考虑以下几点:
(1)要学习跟掌握RS-232接口标准,了解知道那个是接收数据的接口,那个是发送数据的端口。
(2)要掌握MicrosoftCommunicationsControl6.0开发工具,利用软件程序实现异步通信,根据自身的能力,编程好的自己编,不行就借助参考书来进行软件的编程。
(3)要设置参数,例如传输速率、检验方式、以及停止位等参数,这个可以根据系统、个人进行设置。
一般默认为“9600,8,n,1”这个参数。
(4)利用MSComm控件完成PC机间的串口通信。
在这个环节里,要知道在VC软件中如何增加工程,并在工程中怎样增加控件。
(5)利用MicrosoftCommunicationsControl6.0来做用户界面,这样编程灵活性大,并且能够将主要工作集中在串口编程方面。
(6)由于在两个com口实现异步通信,要把两个口的参数设置成一样的值。
鉴于电脑一般有一个com端口,要考虑再用其他电脑或者是利用软件进行虚拟一个端口进行异步通信。
3.2系统分析
本次课程设计,目的是在VC6.0的平台下利用MSComm控件实现异步通信。
根据设计的目的,我作了以下流程图,其流程图如下所示:
图3-1系统流程图
根据以上的流程图,做出以下详细的系统分析。
1)串口参数设置模块
先对串口1和串口2进行初始化,设置输入、输出缓冲区,设置波特率、停止位,数据位,校验位。
我就选默认值,设为“9600,8,n,1”。
因为发送的字符先预留在缓存区,再从缓存区一字符一字符读出,所以设缓冲区是很有必要的。
2)发送数据模块
由于这次课程设计是以异步通信为目的,所以发送的字符,在串口初始化,参数都设置好以后,运行编程软件,进行串口异步通信。
发送数据是要调用onbuttonsend()函数,再调用onComm()函数进行串口处理,其过程是将要发送的字符保存在缓冲区,再从再从缓存区一字符一字符读出。
3)接收数据模块
onComm()函数从缓冲区读出字符后,经处理后的字符经串口接收并在接收编辑框中显示。
通过串口,软件编程共同完成异步通信,依据以上的系统分析,详细的实现此次课程设计的意义,发挥系统分析的作用。
四、详细程序设计及调试
4.1程序设计
1)建立工程:
打开VC++6.0建立基于对话框的MFC应用程序my。
2)在项目中插入MSComm控件:
工程->增加到工程->ComponentsandControls->双击RegisteredActiveXControls->选择MicrosoftCommunicationsControl,version6.0->Insert,按默认值添加,多了个电话图标,这是增加后串口通信控件。
3)界面布局:
删除确认、取消和提示框,添加“电话”(MicrosoftCommunicationsControl,version6.0图标)、静态文本、按钮、编辑框,拖动添加的控件,根据自己的爱好布局,为后面的设计做准备。
4)初始化串口:
设置MSComm控件的属性
查看->建立类向导MFCClassWizard->MemberViariable,选择ClassName为CmyDlg的类,ControlID为MSCOMM1,双击它,为它添加控制变量m_ctrlComm类似的,选择其它项修改。
近而对串口进行初始化,设置串口1和串口2的输入缓冲区为1024bits,输出缓冲区为512bits,以字符的方式传送,设置串口1和串口2的波特率、数据位、校验位和停止位,我设置为"9600,n,8,1"这一数据。
初始化程序如下:
//初始化COM1
m_mscom1.SetCommPort
(1);//串口1
m_mscom1.SetInBufferSize(1024);//设置输入缓冲区的大小,Bytes
m_mscom1.SetOutBufferSize(512);//设置输入缓冲区的大小,Bytes
if(!
m_mscom1.GetPortOpen())//打开串口
{
m_mscom1.SetPortOpen(true);
}
m_mscom1.SetInputMode
(1);//设置输入方式为二进制方式
m_mscom1.SetSettings("9600,n,8,1");//设置波特率等参数
m_mscom1.SetRThreshold
(1);//为1表示有一个字符即引发事件
m_mscom1.SetInputLen(0);
//初始化COM2
m_mscom2.SetCommPort
(2);//串口2
m_mscom2.SetInBufferSize(1024);//设置输入缓冲区的大小,Bytes
m_mscom2.SetOutBufferSize(512);//设置输入缓冲区的大小,Bytes
if(!
m_mscom2.GetPortOpen())//打开串口
{
m_mscom2.SetPortOpen(true);
}
m_mscom2.SetInputMode
(1);//设置输入方式为二进制方式
m_mscom2.SetSettings("9600,n,8,1");//设置波特率等参数
m_mscom2.SetRThreshold
(1);//为1表示有一个字符即引发事件
m_mscom2.SetInputLen(0);
returnTRUE;//returnTRUEunlessyousetthefocustoacontrol
}
5)添加串口事件消息处理函数OnComm()
查看->建立类向导MFCClassWizard->MessageMaps,在ClassName中选择类CmyDlg,再在ObjectIDs中选择IDC_MSCOMM1,然后在Message中双击消息OnComm,在弹出的对话框中将函数名改为OnComm,单击“OK”,就可以加入串口事件的消息处理函数。
Oncomm()的功能是实现两个com端口之间的响应,比如端口1向端口2发送数据,就会调用Oncomm()函数,使在端口2的显示编辑框中接收端口1发送的字符,如图4-1所示。
图4-1添加串口消息处理函数onComm()
响应函数的C++语言程序如下:
voidCMscommDlg:
:
OnCommMscomm1()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
UpdateData(TRUE);
//定义一些临时变量
VARIANTvariant_inp;
COleSafeArraysafearray_inp;
longi=0;
intlen;
BYTErxdata[1000];
switch(m_mscom1.GetCommEvent())
{
case2:
//表示接收缓冲区内有字符
{
//读取缓冲区数据
variant_inp=m_mscom1.GetInput();
//将VARIANT型变量值赋给ColeSafeArray类型变量
safearray_inp=variant_inp;
//获得数据长度
len=safearray_inp.GetOneDimSize();
//将数据保存到字符数组中
for(i=0;i{
safearray_inp.GetElement(&i,&rxdata[i]);
}
//字符串结束
rxdata[i]='\0';
}
m_recv1+=rxdata;
UpdateData(false);
break;
default:
break;
}
}
6)发送及接收数据
先为发送按钮添加一个单击消息,即BN_CLICKED处理函数,打ClassWizard->MessageMaps,选择类CMyDlg,选择IDC_BUTTON_MANUALSEND,双击BN_CLICKED,添加OnButtonManualsend()函数,如图4-2所示。
发送的数据先预留到缓冲区,调用Oncomm()函数从缓冲区中读出来,经处理后的字符经串口接收并在接收编辑框中显示。
图4-2添加发送按钮函数
由于在这次课程设计中,我用了四个按钮,两个com端口各有两个按钮,一个发送,一个清除,就以一个com口的按钮为例,它的C++程序实现程序如下所示:
//COM1发送数据响应函数
voidCMscommDlg:
:
OnBtnCom1send()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
UpdateData(TRUE);
CByteArraysendArr;
WORDwLen;
//获得发送数据长度
wLen=m_send1.GetLength();
//给变量sendArr设置长度
sendArr.SetSize(wLen);
//把数据赋给CByteArray类型变量用于发送数据
for(inti=0;i{
sendArr.SetAt(i,m_send1.GetAt(i));
}
//发送数据
m_mscom1.SetOutput(COleVariant(sendArr));
}
//删除COM1发送数据框数据
voidCMscommDlg:
:
OnBtnCom1delete()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
m_send1="";
U