您好,欢迎访问三七文档
首先,我们来大概的回忆一下单片机的串口通信。8051单片机的串行接口由数据缓冲寄存器SBUF、移位寄存器、串行控制寄存器SCON组成。8051单片机的串行接口是一个可编程的全双工通信接口,通过软件编程可以作为通用异步接收和发送器使用,也可作为同步移位寄存器,还可实现多机通信。其帖格式有8位、10位和11位,通过T1或T2设置各种波特率。1.1串行口工作原理在发送和接收数据前,先对串行口进行初始化设置,要明确串行口的工作方式、波特率等。1.发送数据发送数据,由累加器A送入发送缓冲寄存器SBUF,在发送控制器控制下组成帧结构,并自动以串行方式从TXD输出,每发送完一帧TI置位,可以通过中断方式或查询方式来了解数据的发送情况。值得注意的是TI只能用软件复位。2.接收数据单片机每接收完一帧数据,RI置位,通过中断或查询方式来了解数据的接收情况,然后用MOVA,SBUF指令,将接收缓冲寄存器(SBUF)的值送累加器A。RI与TI一样,也只能用软件复位。1.2串行口工作方式8051单片机通过编程可选择4种串行通信工作方式。1.方式0在方式0下,串行口用作同步移位寄存器,以8位数据为1帧,先发送或接收最低位,每个机器周期发送或接收1位,其波特率为fosc/12。串行数据由RXD端输入或输出,同步移位脉冲由TXD端送出。方式0数据发送与接收是无起始位和停止位,先发送或接收最低位,数据格式为:—D0D1D2D3D4D5D6D72.方式1在方式1下,串行口为10位通用异步接口,数据格式为:——0D0D1D2D3D4D5D6D71——发送数据:当执行MOVSBUF,A指令,CPU将1字节的数据写入发送缓冲寄存器SBUF,数据从引脚TXD端输出,当发送完1帧数据后,TI标志置1,可用中断或查询方式来了解数据发送情况,TI只有通过软件复位。接收数据:接收时,先使REN置1,使串行口处于允许接收状态,RI标志为0,串行口采样到RXD由1到0时,确认是起始位0,就开始接收1帧数据。当停止位到来时,RB8位置1,同时,中断标志位RI也置1,用中断或查询方式,通知CPU从SBUF取走接收到的数据。3.方式2和方式3方式2和方式3均为11位异步通信方式,只是波特率的设置方法不同,数据格式为:—0D0D1D2D3D4D5D6D7D81——发送数据:发送前,先要根据能信协议由软件设置TB8,然后将要发送的数据写入SBUF即可启动发送器。接收数据:接收时,先使REN置1,使串行口处于允许接收状态,RI标志为0。在满足这个条件的前提下,再根据SM2的状态和所接收到的RB8的状态,才能决定此串行口在信息到来后是否会使RI置1。如果置1,在中断方式下将申请中断,接收数据。当SM2=0时,不管RB8为0还是为1,RI都置1,此串行口将接收发来的信息。当SM2=1,且RB8为1时,表示在多机能信情况下,接收的信息为地址帧,此时RI置1。串行口将接收发来的地址。当SM2=1,且RB8为0时,表示接收到的信息为数据帧,便不是发给本从机的,此时RI不置1,因而SBUF中所接收的数据帧将丢失。4.多机通信在方式2和方式3下,有一个专门用于多机通信的功能,这一功能使它可以方便地应用于集散分布系统中,这种系统采用一台主机和多台从机之间通信。多机通信的实现,主要靠主、从机之间正确地设置与判断多机通信控制位SM2和发送或接收的第9位数据位。在硬件上,所有从机的TXD接主机的RXD,所有从机的RXD接主机的TXD。在编程序前,首先要给从机地址编号,如分别为00H、01H、02H等,主机设置在工作方式2或方式3,TB8=1,从机初始化时设置SM2=1,处于方式2或方式3的允许接收状态。主机与从机通信前,主机先发送一个地址字节(地址字节和数据字节可用第9位数据位来区别,第9位为1表示发送的是地址)给从机,从机接收到主机发来的信息时,第9位RB8若为1,则置位中断标志位RI,并在中断后判断主机送来的地址与本机是否相同,若相同,则被寻址的从机设置成SM2=0,准备接收即将从主机送来的数据帧,未被选中的从机保持SM2=1的状态。当主机发送数据时,应置TB8为0,此时,虽各从机处于接收状态,但由于TB8=0,所以只有SM2=0的从机才接收数据,其余从机保持SM2=1状态。1.3串行口控制串行口控制与串行口控制寄存器SCON、电源控制寄存器PCON、串行口发送/接收缓冲区SBUF中断允许寄存器IE、中断优先级、定时控制寄存器TCON及方式控制寄存器TDOM有关。1.串行控制寄存器SCONSCON是一个可位寻址的专用寄存器,地址为98H,用于串行数据通信的控制,位功能如下:SM0SM1SM2RENTB8RB8TIRISM0、SM1:串行口工作方式选择位。工作方式的选择如表8.1所示下。表8.1串行口工作方式SM0SM1工作方式功能波特率000同步移位寄存器FOSC/120118位格式2SMOD/32×T1溢出率1029位格式FOSC/32或FOSC/641139位格式2SMOD/32×T1溢出率SM2:多机通信控制位。在方式2或方式3下,如果SM2=1,当RB8=1(RB8为收到的第9位数据),接收数据送SBUF,并产生中断请求(RI=1),否则丢失8位数据。在方式2或方式3下,如果SM2=0,无论RB8=0或1,接收数据装入SBUF,并产生中断(RI=1)。在方式1下,如果SM2=1,则只有接收到有效的停止位时,才激活RI;如果SM2=0,接收一帧数据,停止位进处RB8,数据进入SBUF,才激活RI。在方式0下,SM2只能为0。REN:允许接收位。由软件置位或清0。REN=1,允许接收;REN=0,禁止接收。TB8:发送数据位。在方式2或方式3下,将要发送的第9位数据放在TB8中。可根据需要由软件置位或复位。在多机通信中,TB8=0表示主机发送的是数据,TB8=1表示主机发送的是地址。RB8:接收数据位。方式0不使用这位。方式1下,如果SM2=0,RB8的内容是接收到的停止位。在方式2或方式3下,存放接收到的第9位数据。TI:发送中断标志位。在方式0下,发送完第8位数据时,TI=1。在其它方式下,开始发送停止位时,TI=1。在任何工作方式下TI必须由软件清0。RI:接收中断标志位。在方式0下,接收完第8位数据时,RI=1。在其它方式下,接收到停止位时,RI=1。在任何工作方式下RI也必须由软件清0。2.串行口波特率设置串行口波特率设置与串行口工作方式及定时控制寄存器TCON、方式控制寄存器TDOM及电源控制寄存器有关。(1).T溢出率的计算在串行通信方式1和方式3下,使用定时器T作为波特率发生器。T可以工作于方式0、方式1和方式2,由于定时器方式2是具有自动重装功能的8位定时器,因此常选用它。溢出周期=(12/fosc)*(256--X);式中X为定时器初值,fosc为晶振频率。溢出率=1/溢出周期(2).波特率的计算(1)方式0和方式2的波特率方式0的波特率=fosc/12方式2的波特率=(2SMOD/64)×fosc(2)方式1和方式3的波特率方式1和方式3的波特率=2SMOD×fosc/[32×12(256-X)](3).波特率的设置TMOD:工作在方式2PCON:只有工作在方式1、2、3时,如果PCON的SMOD为高电平,则通信整度加倍。SMOD———计算定时器初值:定时器初值是由波特率=2SMOD×fosc/[32×12(256-X)]计算得到。中断设置:SETBES;开串行中断SETBEA;中断启动串行中断优先级由中断优先控制寄存器IP中的PS决定。农民也学单片机2009-05-0210:12好,串口通信的基本概念和通信规则我们已经大概的有一个了解了,相信大家都已经熟记在心了。下面,我们开始编写上位机了。先让我们来了解一下串口通信上位机编写的方法有哪些以及要用到哪些技术,其实到现在为止我自己也是一窍不通,也没有具体的书参考,先我们还是这样画葫芦画下去吧,本人对VC的研究也不是很透彻,还得去学好C++,不过一步一步慢慢来吧,告诉自己坚持到底,要坚持到底!方法一:使用VC++提供的串行通信控件MSComm首先,在对话框中创建通信控件,若Control工具栏中缺少该控件,可通过菜单Project--AddtoProject--ComponentsandControl插入即可,再将该控件从工具箱中拉到对话框中。此时,你只需要关心控件提供的对Windows通讯驱动程序的API函数的接口。换句话说,只需要设置和监视MSComm控件的属性和事件。----在ClassWizard中为新创建的通信控件定义成员对象(CMSCommm_Serial),通过该对象便可以对串口属性进行设置,MSComm控件共有27个属性,这里只介绍其中几个常用属性:----CommPort设置并返回通讯端口号,缺省为COM1。----Settings以字符串的形式设置并返回波特率、奇偶校验、数据位、停止位。----PortOpen设置并返回通讯端口的状态,也可以打开和关闭端口。----Input从接收缓冲区返回和删除字符。----Output向发送缓冲区写一个字符串。----InputLen设置每次Input读入的字符个数,缺省值为0,表明读取接收缓冲区中的全部内容。----InBufferCount返回接收缓冲区中已接收到的字符数,将其置0可以清除接收缓冲区。----InputMode定义Input属性获取数据的方式(为0:文本方式;为1:二进制方式)。----RThreshold和SThreshold属性,表示在OnComm事件发生之前,接收缓冲区或发送缓冲区中可以接收的字符数。----以下是通过设置控件属性对串口进行初始化的实例:BOOLCSampleDlg::PortOpen(){BOOLm_Opened;......m_Serial.SetCommPort(2);//指定串口号m_Serial.SetSettings(4800,N,8,1);//通信参数设置m_Serial.SetInBufferSize(1024);//指定接收缓冲区大小m_Serial.SetInBufferCount(0);//清空接收缓冲区m_Serial.InputMode(1);//设置数据获取方式m_Serial.SetInputLen(0);//设置读取方式m_Opened=m_Serail.SetPortOpen(1);//打开指定的串口returnm_Opened;}----打开所需串口后,需要考虑串口通信的时机。在接收或发送数据过程中,可能需要监视并响应一些事件和错误,所以事件驱动是处理串行端口交互作用的一种非常有效的方法。使用OnComm事件和CommEvent属性捕捉并检查通讯事件和错误的值。发生通讯事件或错误时,将触发OnComm事件,CommEvent属性的值将被改变,应用程序检查CommEvent属性值并作出相应的反应。在程序中用ClassWizard为CMSComm控件添加OnComm消息处理函数:voidCSampleDlg::OnComm(){......switch(m_Serial.GetCommEvent()){case2://串行口数据接收,处理;}}----方法二:在单线程中实现自定义的串口通信类----控件简单易用,但由于必须拿到对话框中使用,在一些需要在线程中实现通信的应用场合,控件的使用显得捉襟见肘。此时,若能够按不同需要定制灵活的串口通信类将弥补控件的不足,以下将介绍如何在单线程中建立自定义的通信类。----该通信类CSimpleComm需手动加入头文件与源文件,其基类为CObject,大致建立步骤如下:----(1)打开串口,获取串口资源句柄----通信程序从CreateFile处指定串口设备及相关的操作属性。再返回一个句柄,该句柄将被用于后续的通信操作,并贯穿整个通信过程。CreateFile()函数中有几个值得注意的参数设置:串口共享方式应设为0,串口为不可共享设备;创建方式必须
本文标题:上位机界面编程
链接地址:https://www.777doc.com/doc-3254006 .html