如何实现(电脑)PC机与单片机AT89C51的串行通信

如何实现(电脑)pc机与单片机at89c51的串行通信
在windows95下使用串口api函数实现pc机与单片机at89c51的串口通信,重点介绍计算机采用事件驱动i/o方式的函数编程及单片机串口中断发送、接收程序的实现。
关键词:windows95 单片机at89c51 rs-232接口 rs-485接口 串行通信
在以单片机为基础的数据采集和实时控制系统中,通过计算机中的rs-232接口进行计算机与单片机之间的命令和数据传送,就可以利用计算机对生产现场进行监测和控制。由于计算机上的rs-232所传送的距离不超过30m,所以,在远距离的数据传送和控制时,可以用max485的接口转换芯片将rs-232转换成rs-485协议进行远距离传送。在发送和接收端都进行协议转换后,rs-485协议对数据传送来说是相对透明的,所以依然可以使用计算机中的rs-232进行远距离的数据传送和控制。在最简单的rs-232直接传送通信系统中,只要发送和接收双方同时准备好,仅用信号发送端(txd),信号接收端(rxd)和信号地(gnd)3根线即可进行通信;若以应答方式进行数据通信,可使用请求发送(rts)、清除发送(cts)或数据终端准备(dtr)、数据装置准备(dsr)进行硬件握手。在windows95下,可以很方便地使用win32通信api函数来实现这些硬件的握手以及数据的传送。在89c51单片机系统中,分别从p3.0和p3.1引出串口线rxd和txd通过专用的电平转换芯片转换成rs-232接口标准的电平,这样,二者之间就可以通过rs-232接口进行数字信号的传送。单片机也可以以直接传送或应答握手的方式进行数据通信,但由于握手方式占用其他的端口,而单片机的端口数量有限,所以,计算机与单片机的通信常采用直接传送的方式,本文将重点介绍。
1 windows95下的通信编程
windows95通信体系提供了1个改进的串行应用程序接口sapi用来进行交互式串行通信。其中,串口和其他通信设备是作为文件进行处理的,串口的打开、关闭、读取和写入所用的函数和操作文件的函数相同。
通信会话以调用createfile函数开始,createfile函数为读访问或写访问打开串口,打开成功后返回该串口句柄,供读写串口时使用。createfile函数的使用如下:
createfile(szdevice,fdwaccess,fdwsharemode,lpsa,fdwcreate,fdwattrsandflags,htemplatefile)
其中,第1个参数szdevice是要打开的串口逻辑名,如com1或com2;第2个参数fdwaccess指定串口的访问类型,如读、写或两者兼而有之,大部分通信是双向的,因而通常设置为:genericread|genericwrite;第3个参数fdwsharemode指定串口的共享属性,串口不能共享,所以它必须为0;第4个参数lpsa引用安全性属性结构;第5个参数fdwcreate指定如果createfile正被已有的文件调用时应做些什么,既然串口总是存在,此参数就必须被设置为openexisting。第6个参数fdwattrsandflags描述了该端口的各种属性,对串口而言,唯一有意义的设置是fileflagoverlapped,指定该设置时,端口i/o可以在后台进行;最后1个参数htemplatefile是指向模板文件的句柄,当端口打开时,该参数为null。
打开串口后,在windows95下可以对串口进行合适的配置。windows95提供了commprop结构,commprop结构中包含了对串口允许的设置,如波特率、数据位数、停止位的个数以及奇偶校验方法等,如果串口连接到调制解调器,commprop结构中还包含调制解调器支持的设置。但commprop结构给出的只是单纯的信息,它不能用来改变串口的设置。windows95下串口设置的改变是通过改变它的dcb结构来实现的,dcb结构中包含了所有串口的设置,其中包括硬件的握手、流控制等。
windows95提供getcommstate函数来得到当前串口的设置情况,该函数接收1个打开的端口句柄和1个指向dcb结构的指针,在dcb结构中返回信息,getcommstate函数的补充函数是setcommstate函数,setcommstate函数将dcb结构中的内容写向串口设置,这2个函数的调用如下:
boolgetcommstate(hcomm,&dcb)
boolsetcommstate(hcomm,&dcb)
其中,hcomm为打开串口的句柄,dcb为1个指向dcb的结构。
windows95中实现串口的读写函数与文件的读写函数相同,读写函数的使用格式如下:
readfile(hcomm,inbuff,nbytes,&nbytesread,&overlapped)
writefile(hcomm,outbuff,nbytes,&nbyteswrite,&overlapped)
其中,第1个参数是打开串口的句柄,第2个参数是数据所使用的缓冲区,第3个参数是要读取的字节数,第4个参数是实际读取的字节数,实际读取的字节数可能小于要读取的字节数,最后1个参数指向1个覆盖似的结构,当createfile中dwattrsandflags参数设置为fileflagoverlapped时,此参数可以指定1个overlapped结构,使数据的读写操作在后台进行。
读写端口可以通过4种技术来实现:查询、同步i/o、异步i/o(后台i/o)和事件驱动i/o。查询方式直接、易于理解,但占用大量cpu时间;同步i/o直到读取所指定字节数或超时时才返回,这样很容易长时间地阻塞线程;异步i/o可以在后台读写数据,而在前台做其他的事情;事件驱动i/o是由windows95通知应用程序某些事件什么时候发生,然后根据所发生的事情来对串口进行操作。
这4种不同的技术,各有利弊和自己适用的领域,所以,在不同的通信系统中,可以根据不同的要求采用不同的技术。在监测系统中,由于事件的偶然性和要求传送的实时性,计算机常采用事件驱动i/o方式来进行现场监测。
在事件驱动i/o方式下,windows95报告给应用程序的事件由函数getcommmask返回,改变返回的事件时,可以使用setcommmask函数设置,这2个函数的调用如下:
getcommmask(hcomm,&dwmask)
setcommmask(hcomm,dwmask)
第1个参数是打开串口的句柄,第2个参数是要等待的1个或多个事件的掩码。在用setcommmask设置了有用的事件后,应用程序调用waitcommevent函数来等待事件的发生,直到事件发生,waitcommevent函数返回。waitcommevent函数使用格式如下:
waitcommevent(hcomm,&dwevent,&overlapped)
第1个参数是打开串口的句柄,第2个参数是返回的事件,第3个参数是指定同步或者异步操作。当函数返回后,可根据返回的事件掩码进行相应的串口操作。
完成通信后,串口应该关闭,否则,它始终处于打开状态,其他应用程序就不能打开或使用它。关闭串口的函数为:closehandle(hcomm),其中,hcomm为打开的串口句柄。
2 单片机下的通信编程
单片机89c51的串行端口有4种工作方式,通过编程设计,可以使其工作在任一方式,以满足不同场合的需要。其中,方式0主要用于外接移位寄存器,以扩展单片机的i/o电路;方式1主要用于双机之间或外设电路的通信;方式2、3除有方式1的功能外,还可用作多机通信,以构成多微机系统,方式2、3的区别在于波特率的不同。
单片机的串行通信的波特率可以程控设定,在不同的工作方式下,由时钟振荡频率的分频值或由定时器t1的定时溢出时间确定。
单片机的串行端口有2个控制寄存器,用来设置工作方式、发送或接收的状态、特征位、数据传送的波特率以及中断标志ti和ri。
单片机的串行端口有1个数据寄存器sbuf,该寄存器为发送和接收所共有,在一定条件下,向sbuf写入数据就启动了发送过程,读sbuf就启动了接收过程。
单片机可以采用循环方式或中断方式实现串行数据的传送。在循环方式下,单片机循环对数据寄存器sbuf进行读写来实现数据的接收和发送;在中断方式下,对方式1、2来说,1帧数据发送或接收完后,ti/ri自动置1,请求串行中断,若cpu响应中断,则执行串行中断服务程序,并把ti/ri清0以再次响应中断。对在方式2、3下的接收,还要视串口控制寄存器scon的设置才可确定ri是否被置位以及串口中断是否开放。
实时控制中,由于事件的突发性,常采用中断的方式进行数据传送,中断方式能更大限度地提高资源的利用率,使cpu在不进行数据通信时做其他的工作。下面重点介绍单片机在方式1下的中断方式编程。
方式1是10位异步通信方式,其中包括1个起始位,8个数据位和1个停止位。波特率由定时器t1的溢出率和串口控制寄存器smod的状态确定,在cpu的晶振为11.0592mhz时,波特率常采用9600b/s。
对sbuf进行写操作就可启动发送,在发送移位时钟的同步下,从txd先送出起始位,然后是8位数据位,最后是停止位,这样,1帧数据发送完,中断标志ti置位。
在允许接收的条件下(ren=1),当rxd出现由1到0的负跳变时,即被当成是串行发送来的1帧数据的起始位,从而启动1次接收过程。当8位数据接收完,并检测到高电平停止位后,即把收到的8位数据装入sbuf,置位ri,1帧数据的接收过程就完成了。
下面是单片机以方式1在直接传送下的中断接收和发送程序。由于没有使用通信握手,所以通信双方都应做好通信准备。在计算机接收、单片机发送时,由计算机先发送字母“r”,通知单片机计算机已准备好,然后计算机在事件驱动i/o方式下等待接收到字符“y”;当单片机接收到“r”时,向计算机发送“y”,表示单片机也已准备好,这样,一旦计算机接收到“y”就表示双方都已准备好,二者之间就可以进行数据交换了。在计算机发送、单片机接收时,计算机发送1帧数据,单片机响应中断,接收数据。单片机程序的具体实现过程如下:
org 0000h
ajmpstart
org0023h;串行中断入口
ljmps&r
org0100h
start:mov tmod,#20h ;设置定时器t1方式2
movpcon,#00h;使smod为0
movtll,#0fdh;波特率为9600b/s
movthl,#0fdh
setbea;开全局中断
clret1;关t1中断
setbes;开串行中断
setbtrl;开t1定时
movscon,#50h;串行方式1,允许接收
sjmp$
s&r:movc,ri
jcrecive;ri为1,执行接收子程序
sjmpsend;否则,执行发送子程序
recive:mova,sbuf;接收数据
clrri
cjnea,#52h,re;是否接收到“r”
mova,#59h;是,发送“y”
movsbuf,a
sjmpendtr
re:mov @rl,a;r1为接收数据存放地址
incr1
sjmpendtr
send:mova,@r0;发送数据,r0为存放数据的地址
movsbuf,a
jnbti,$
clrti
incr0
endtr:reti;中断返回
3 结束语
串口通信是一种广泛应用于各个领域的通信方式,由于目前大部分计算机都安装了windows95操作系统,所以本文具体实现了在windows95下利用它的sdk函数来与单片机进行串口通信。本文所提出的实现函数在所有当前流行软件如vc++、delphi等中都可实现。它不仅可以用于近距离的rs-232通信,而且,还可以实现中远距离rs-485通信。在使用该程序的通信系统中,近远距离的通信都取得良好的效果。
参考文献
1 mirhoca,terrissea著,贺军,高胜友译.windows95通信编程.北京:清华大学出版社,1997
 2 陈光东,赵性初.单片微型计算机原理与接口技术.武汉:华中理工大学出版社,1993

LED驱动设计技巧及应用方案集锦
NVIDIA的一个可能解决方案是利用AI的力量
小型无人机全姿态增稳控制系统的设计与实现
学习一下ARM的智能功率分配技术
为什么CAN能取代RS485?
如何实现(电脑)PC机与单片机AT89C51的串行通信
物联网平台的未来会是怎样的
报道称M1 Mac mimi功耗仅为Intel芯片版本的1/3
基础定时器实验
六个可有效提升Linux服务器安全性的工具和源码
网络升级的样板——易飞扬特色扇出型光模块
Dialog在SmartServer™生态系统中增加AI和数据分析合作伙伴,引领工业数字化转型
思林杰收上交所监管工作函
三位量子精密测量研究者荣膺“墨子量子奖”
兆易创新推出GD32VW553系列Wi-Fi 6 MCU
ADS7846控制器的特性及引脚图
新型橡胶复合材料有望应用于柔性电子器件中
加速度传感器(MPA1064A)实测---LOTO虚拟示波器
俄罗斯总统普京计划将对该国的加密货币部门进行立法监管
社区说 | 精益求精: Flutter 技巧专题篇