田社平, 方向忠, 张 峰
(上海交通大学 电子信息与电气工程学院,上海 200240)
串口是目前工业通信中较为普遍的一种通信方式,同时在单片机教学中占据重要地位[1-4]。传统的串口通信实验往往需要一根串口线连接两个终端(两台PC机,或者一台PC一个单片机系统,或者两个单片机系统),其对硬件仿真器依赖性较强。由于很多仿真器不能做到完全硬件仿真,因而可能造成仿真时正常,而实际运行时出现错误的情况,或者造成仿真不能通过,但是实际运行正常的情况。当单片机芯片型号发生较大变化时,需要配置新的仿真器,增加了资金投入。因此,开发一种虚拟的串口通信教学实验系统,具有良好的教学价值。例如,可以利用Keil和虚拟串口驱动(VSPD)即可达到这一目的[5-7],但这样的实验系统具有操作较为复杂、显示不够直观、不能加入硬件设计等缺点。
本文讨论一种基于VSPD和Proteus[8-9]串口调试与实验方法,可以在一台PC机上完成原本需要两个终端才能实现的串口通信。首先从虚拟串口的结构和原理,阐述串口通信的基本原理。接着以一个实例给出了基于VSPD的串口通信的具体实现过程。该例实现了PC机与单片机之间的串口通信,PC机端串口通信程序采用VC++6.0编写,单片机选用Intel公司的AT89C51,在Proteus仿真软件中用汇编语言编写。
虚拟串口驱动程序是一个标准的Win32驱动程序模型(WDM)的设备驱动程序,它面向串口用户程序,为用户提供标准而完整的串口设备接口。该驱动程序的系统I/O调用接口以及读写控制完全仿造标准的串口驱动程序制作,所以从用户角度看,虚拟串口的使用和普通串口没有任何区别。
虚拟串口的应用类型有很多,基于串口教学实验的需要,这里只介绍其中一种——互联型虚拟串口。互联型虚拟串口是将两个虚拟串口的数据通道连接起来。其效果相当于用串口回环线将两个物理串口连接起来。除了将串口数据线TX和RX交叉连接以外,互联型虚拟串口程序还将RTS、CTS、DTR、STR等控制线也进行互连,如图1所示。
图1 互联型虚拟串口模拟的串口回环线
这些连接都是软件意义上的,并没有实际物理线相联。这根使用软件来模拟的串口回环线,实际上是使用线程通信完成的,其原理图如图2所示。由该图可知,两个虚拟串口连接以后,任何串口发送的数据将会被另外一个虚拟串口所接收。
图2 互联型虚拟串口原理
虚拟串口驱动程序有很多,常用的有VSPD、VSPM和SUDT SerialNull 等。而VSPD以其操作简单,容易上手等特点倍受青睐。VSPD全称为Virtual Serial Port Driver XP,是Eltima软件公司的一款产品。它能成对地添加虚拟串口,最多可虚拟256个串口。VSPD虚拟串口对的操作界面如图3所示。
图3 VSPD虚拟串口对
VSPD可以和Proteus结合,添加的一对虚拟串口被设定为通过非MODEM(三线制)串口连接在一起,就像两个真实的物理串口一样,从而实现在一台PC机上模拟两个软件的串口通信。
建立单片机与PC机之间的串口通信,单片机电路如图4所示。要求单片机的4个开关控制4盏LED灯,当开关合上时,相应的灯亮,同时将信息发送给PC机,如“P1.x is on. Lx lights.”,其中x取0~3,分别与SW1~4对应;PC机接收到信息后显示,同时向单片机发送字符(0-9,A-F),并通过单片机控制数码管显示相应的数字。PC机串口编程采用VC++6.0,单片机采用89C51汇编语言编程实现。串口通信格式为:1 200 bit/s波特率,8位数据,无校验,1个停止位。
图4中,SCMR为虚拟接收端口,用来显示单片机接收到的数据;SCMT为虚拟发送端口,用来显示单片机发送的内容。P1为串口物理接口模型COMPIM,用来与外部进行RS-232串口通信。在仿真实验时,必须在相应的“Edit Component”对话框中设置与实验一致的串口通信参数。其中COMPIM的设置界面如图5所示。
图4 串口实验下位机电路
图5 串口通信参数设置界面
为了使例程具有一般性,单片机采用通用的89C51,在Proteus上运行实现[10-12]。89C51的时钟频率取11.059 2 MHz,单片机选用串口方式1,定时器方式2,SMOD=1。由波特率公式:
波特率=2SMOD/32×T1溢出率,T1溢出率=时钟频率/[12×(256-TH1初值)]
可以求得T1的溢出率为1200/(2/32)=19200,从而算得定时初值为
256-11.0592×106/(19200×12)=208=0D0H
单片机的主程序如下:
MOV SP, #60H
MOV SCON, #50H ;串口方式1,允许接收
MOV TMOD, #20H ;定时器1为方式2
ORL PCON, #80H ; SMOD=1
MOV TH1, #0D0H ;波特率为1200
MOV TL1, #0D0H
SETB TR1
MOV DPTR, #CHSE ;发送’Hello, world!’
LP1: CLR A
MOVC A, @A+DPTR
CJNE A, #’’, SE1 ;判是否到发送结束位
LJMP LP2
SE1: LCALL SEND ;发送子程序
LCALL DELAY ;延时子程序
INC DPTR
LJMP LP1
LP2: MOV DPTR,#TABLE ;初始化显示‘5’
MOV A, #05H
MOVC A, @A+DPTR
MOV P0, A
CLR A
CLR DPTR
LP: JNB P1.0, L1 ;检测按键,如果P1.0按下转L1
JNB P1.1, L2
JNB P1.2, L3
JNB P1.3, L4
JNB RI, LP ;等待接收1个字符
CLR RI
MOV A, SBUF ;接收到的字符送A
LCALL DELAY
MOV RDATA, A
LCALL SEND
LCALL DELAY
MOV DPTR, #TABLE
LCALL CHANGE ;ASCII码转16进制数子程序
MOV A, RDATA
LCALL DISP ;显示子程序
LJMP LP
程序中,SEND为发送子程序,DELAY为延时子程序,CHANGE为数制转换子程序,完成ASCII码到十六进制的转换,Lx(x为1,2,3,4)为开关操作程序,即实现按下开关,相应的指示性语句发送到PC机的功能。CHSE地址存放的是初始字符串“Hello, world!”,TABLE地址存放的是7段码值。由于篇幅所限,具体代码从略。
Win32中基于VC++6.0的常用串口通信程序一般可以用两种方法实现[13-14]:①利用MSComm ActiveX串行通信控件;②使用Windows API通信函数。本实验中采用MSComm ActiveX控件进行编程。MSComm提供了两种处理通信问题的方法:①事件驱动法,当串口上发生某一事件时,使用MSComm控件的OnComm事件可以捕获并处理这些事件;②查询法,每当应用程序执行完某一串行口操作后,将不断检查MSCommEvent属性以检查执行结果或者检查某一事件是否发生。本实验中采用第一种方法,在串口接收缓冲区中有字符时接收。
实验中MSComm控件涉及的几个重要属性如表1所示。
表1 实验中MSComm的几个属性
根据表1的控件属性设置好正确的串口通信参数配置、数据获取方式和通信响应类型等,通过Output发送数据,由Input在OnComm函数中接收数据。图6为VC++6.0实现的串口通信实验程序流程框图。
图6 串口实验PC机程序流程
首先打开VSPD增加一对虚拟串口对,如COM1和COM2;接着运行C++程序,设置好串口号为COM2,波特率为1 200,8位数据位,1位停止位和无奇偶校验之后,打开串口;然后运行Proteus软件,对串口物理接口,虚拟接收/发送端口设置对应的通信参数,串口号选为COM1,点击Proteus左下方的运行键。最后的结果如图7所示。
程序通信后,首先由单片机向PC机发送字符串"Hello world!";当按下P1.x时,单片机就向PC机发送"P1.x is on. Lx lights."(x为0到3中的一个整数),同时相应的LED就会点亮。由单片机向PC机发送过程中,PC机和虚拟发送端口同时显示发送的内容。当PC机向单片机发送字符A时,虚拟接收端口和数码管就会显示"A"。由此,实验任务得到实现。
(a) PC端串口通信界面
虚拟端口发送显示
虚拟端口接收显示数码管显示
(b) 单片机端显示界面
图7 串口通信实验仿真结果
本实验利用虚拟串口驱动程序VSPD和虚拟仿真软件Proteus实现了串口通信功能,具有实验现象直观、软件调试方便的特点。在调试阶段不受时间地点和器材的限制,从而减少硬件的使用,给开发和调试带来了很大的灵活性,能取得事半功倍之效,提高学生的研究能力和学习兴趣。
尽管本实验中的单片机采用目前单片机教学中主流的MCS-51系列单片机,但本文方法也适用于各类单片机、微控制器的串口通信开发与调试,程序的编写也可采用C语言以简化开发过程[15]。同样,PC机端串口程序也可采用不同的语言编写,例如,当用VB或是其他语言实现串口通信程序时,仍可移植本实验设计思路。因此,本实验的实现方案可以根据教学实际进行灵活配置,将教学重点放在对串口通信的理解上,以取得良好的教学效果。
本文给出了虚拟串口通信实验的框架结构和基本实现方法,在实际教学中可以在此基础上增加诸如修改通信参数、进行大数据量传输等实验要求,以满足不同的教学要求。