《单片机系统设计仿真与应用》课件第5章_第1页
《单片机系统设计仿真与应用》课件第5章_第2页
《单片机系统设计仿真与应用》课件第5章_第3页
《单片机系统设计仿真与应用》课件第5章_第4页
《单片机系统设计仿真与应用》课件第5章_第5页
已阅读5页,还剩96页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

5.1串行口工作原理

5.2串行口协议设计

5.3串行口应用设计

5.4小结

习题

5.1.1串行口的专用寄存器

1.串行口控制寄存器SCON

串行口控制寄存器是串行口控制和状态寄存器。SCON包含:串行口工作方式选择位、接收发送控制位以及串行口状态标志位,其位格式如下:5.1串行口工作原理

SM0、SM1(SCON.7、SCON.6):串行口的工作方式选择位,其编码见表5-1,其中fosc为振荡频率。

SM2(SCON.5):多机通信控制位,主要用于方式2和方式3。

REN(SCON.4):串行口接收允许位,由软件置位以允许接收,由软件清0来禁止接收。

TB8(SCON.3):在方式2和方式3中为发送的第9位数据。

RB8(SCON.2):在方式2和方式3中为接收到的第9位数据。

TI(SCON.1):发送中断标志。

RI(SCON.0):接收中断标志。表5-1串行口的工作方式

2.串行口数据缓冲器SBUF

MCS-51单片机内的串行接口部分,具有两个物理上独立的缓冲器:发送缓冲器和接收缓冲器,以便能以全双工的方式进行通信。

3.电源控制寄存器PCON

电源控制寄存器PCON的第7位是与串行口的波特率设置有关的选择位。其位格式如下:

 SMOD(PCON.7):串行口波特率倍增位。

GF1(PCON.3)、GF0(PCON.2):两个通用标志位,由程序使用。

PD(PCON.1)、IDL(PCON.0):CHMOS器件的低功耗控制位。5.1.2串行口的工作方式

1.方式0

方式0为同步移位寄存器输入输出方式。

图5-1(a)为串行口外接一片串入并出移位寄存器74LS164的输出接口电路,该电路用于扩展并行输出口;图5-1(b)为串行口外接一片并入串出移位寄存器74LS165的输入接口电路,该电路用于扩展并行输入口。图5-1方式0发送、接收电路

2.方式1

串行接口工作于方式1时,被定义为10位的异步通信接口,即传送一帧信息需要10位。

串行接口以方式1发送时,数据由TXD端输出。

3.方式2和方式3

串行接口工作于方式2和方式3时,被定义为11位的异步通信接口,即传送一帧信息需要11位。5.1.3波特率的设置

MCS-51单片机串行口通信的波特率取决于串行口的工作方式。四种工作方式的波特率计算公式分别如下:

1.T/C1溢出率的计算

在串行通信方式1和方式3下,使用定时器T/C1作为波特率发生器。

前面我们介绍过定时器定时时间的计算方法,同样,我们设X为时间常数即定时器的初值;fosc为晶振频率,当定时器T/C1工作于方式2时,则有:

溢出周期 =T/C1溢出率

==

2.波特率的设置

由上述可得,当串行口工作于方式1或方式3、定时器T/C1工作于方式2时有波特率 ==由上式可以看出,当X=255时,波特率为最高。如fosc=12 MHz、SMOD=0,则波特率为31.25 kb/s;若SMOD=1,则波特率为62.5 kb/s,这是fosc=12 MHz时波特率的上限。若要求更高的波特率,则需要提高主振频率fosc。在实际应用中,一般是先按照所要求的通信波特率设定SMOD,然后再算出T/C1的时间常数。即X =

我们设SMOD=1,则T/C1的时间常数X的值为X ==

256-=

208=D0H表5-2列出了常用波特率与其他参数的关系。系统振荡频率fosc选为11.0592 MHz是为了使定时器初值为整数,从而产生精确的波特率。表5-2常用波特率与其他参数的关系注:方式0时,BAUD=fosc/12;方式2时,BAUD=2SMOD×fosc/64。5.2.1串行通信接口的基本任务

串行通信接口的基本任务包括:

(1)实现数据格式化。

(2)进行串并转换。

(3)控制数据传输速率。

(4)进行错误检测。

(5)进行TTL与EIA电平转换。

5.2串行口协议设计5.2.2串行通信协议

单片机串口称为“通用异步收发器”(UART,UniversalAsynchronousReceiverandTransmitter)。

1.特点与格式

串行通信异步协议的特点是一个字符一个字符地传输,并且传送一个字符总是以起始位开始,以停止位结束的,字符之间没有固定的时间间隔要求。其格式如图5-2所示。

图5-3表示了传送一个字符E的ASCAII码的波形,当把它的最低有效位写到右边时,就是E的ASCII码1000101=45H。图5-2传送的字符格式图5-3传送字符E的ASCII码的波形

2.起始/停止位的作用

起始位实际上是作为联络信号附加进来的,当它变为低电平时,则告诉收方传送开始。它的到来,表示数据位将接着出现,要准备接收。5.2.3协议的设计

使用串口进行通信,通常包括单片机与主机间的通信、单片机间的通信以及多单片机间的通信三种。5.3.1原理图设计与说明

本章使用的电路原理图如图5-4~图5-7所示。5.3串行口应用设计图5-4单片机与微机通信原理图图5-5多单片机间通信顶层电路图图5-6图5-5中的SUB2子电路原理图图5-7图5-5中的SUB3子电路原理图关于图5-4~图5-7原理图的说明如下:

(1)图5-4是单片机与微机通信原理图;图5-5和图5-6组合在一起是双机通信原理图;图5-5、图5-6和图5-7组合在一起是多机通信原理图。

(2)图5-4中使用了四台虚拟终端。

(3)串口模型器件应选用COMPIM。在ProteusISIS元件库的“Connectors”类的“D-Type”子类中,也有一个串口模型器件CONN-D9F,因该器件在使用时没有仿真模型,将会导致仿真失败,所以要避免选用。

(4) COMPIM器件使用前要进行设置,本章使用的设置结果如图5-8所示。图5-8COMPIM器件使用前的设置

(5)四个虚拟终端也要进行相应的设置。PC_TX代表计算机发送数据,PC_RX用来监视PC接收到的数据,它们的属性设置完全一样,如图5-9所示。MCS_TX和MCS_RX分别是单片机的数据发送和接收终端,用来监视单片机发送和接收的数据,它们的属性设置完全一样,如图5-10所示。图5-9MCS_TX和MCS_RX的设置结果图图5-10PC_TX和PC_RX的设置结果

(6)使用时,原理图中的电阻R1不能少,否则虚拟终端PC_RX将收不到信息。

(7)图5-5、图5-6和图5-7是单片机间通信原理图。

(8)图5-6和图5-7中均有一个按键和一个LED灯,可用于机间通信控制,例如,用SUB2中的按键控制SUB3中的LED灯的亮灭等。

(9)使用器件列表如图5-11所示,在Proteus中输入器件名称即可找到该器件。图5-11元器件列表清单

2.设计说明

根据单片机与微机通信的设计要求。可以看出,单片机与微机采用了以下握手协议:

(1)单片机向微机发送信息,以“-”作为结束符;

(2)当微机接收到结束符“-”后,即向单片机回送信息,并以“-”作为结束符;

(3)当单片机接收到结束符“-”后,将信息显示于液晶屏上。

程序设计流程图如图5-12所示。图5-12单片机与微机通信时的单片机程序流程图

3.设计源码

单片机与微机通信的源程序见例5-1。

【例5-1】

单片机与微机通信的源程序。

#include<reg51.h>

#defineucharunsignedchar

//定义一个长度为16的空串,用于存放接收字符显示

ucharrecdata[16]="";

uchartrdata[16]="FromA:master!";

voidLcd_initialize(void);

voidLcd_display(ucharaddr,uchar*str);

voiddelay(ucharx);//*************串口通信函数——单机通信*****************//

//本单片机(机A)发送一字符串:"FromA:master!";

//微机(用虚拟终端模拟)接收并显示"FromA:master!",然后回送"abc-"

//当接收到微机传送过来的"abc"后在液晶屏中显示出来。

//然后,间隔200 ms后再循环以上过程

voidmain(void)

{ uchari;

Lcd_initialize();

Lcd_display(0x00,“MCS51<---->PC:”);

//第1行显示值

TMOD=TMOD|0x20;

//设置波特率为9600的定时器1方式和初值

TL1=0xfd;TH1=0xfd; //此值对应单片机晶振频率为11.0592 MHz

SCON=0x50;PCON=0x00;

//设置串行口方式

TR1=1;

while(1)

{ i=0;

while(trdata[i]!='\0') //发送字符串

{

SBUF=trdata[i];

while(TI==0);

TI=0;

i++;

}

SBUF='-';//发送结束字符

while(TI==0);

TI=0; i=0;

//i清0,为接收作准备

while(RI==0); //接收应答

RI=0;

recdata[i]=SBUF;

while(recdata[i]!=‘-’)

//传完后,应答A机并显示收到的字符串

{

i++;

while(RI==0);//接收应答

RI=0;

recdata[i]=SBUF;

} recdata[i]=‘\0’;

Lcd_display(0x40,recdata);

//第2行显示

delay(200);delay(200);

//延时200 ms后,继续以上A机和B机的握手过程

}

}

4.仿真结果

运行仿真,结果如图5-13所示。图5-13单片机与主机的发送/接收监视情况

从图5-13中可看出,默认情况下,在PC_T中输入字符后并不会显示出来,为了让输入的字符显示出来,则需要在PC_T界面中单击鼠标右键选中“EchoTypedCharacters”,如图5-14所示。图5-14虚拟终端回显字符的设置5.3.3双机通信设计

1.设计要求

用两个MCS-51单片机进行双机通信设计。具体要求如下:

(1) A机向B机发送字符串。

(2) B机接收到字符串后,向A机发送另一个字符串,循环进行。

(3) B机接收完成点亮LED灯,B机发送完成熄灭LED灯。

2.设计说明

双机通信类似于单片机与主机间的通信。根据设计要求,可得出如图5-15所示的双机程序流程图。图5-15双机通信程序流程图

3.设计源码

双机通信源程序包括主机A的源程序和从机B的源程序,分别如例5-2和例5-3所示。

【例5-2】

主机A的源程序。

#include<reg51.h>

#defineucharunsignedchar

//定义一个长度为16的空串,用于存放接收字符显示

ucharrecdata[16]="";

uchartrdata[16]="FromA:master!";

voidLcd_display(ucharaddr,uchar*str);//LCD显示函数,该LCD与单片机在同一图中voidLcd_initialize(void);

voiddelay(ucharx);

//*************串口通信函数——双机通信*****************//

//本单片机(A机)发送一字符串:"FromA:hjk!";

//另一单片机(B机)接收,接收完成后回送"FromB:slave_1",并在液晶屏中显示"FromA:hjk!"

//当接收到B机传送过来的"FromB:slave_1"后在液晶屏中显示出来。

//然后,间隔200 ms后再循环以上过程

voidserial(void)

{ uchari;

TMOD=0x20;

TL1=0xfd;TH1=0xfd;

SCON=0xd8;PCON=0x00; //设置串行口方式

TR1=1;

while(1)

{

i=0;

while(trdata[i]!='\0') //发送字符串

{ SBUF=trdata[i];

while(TI==0);

TI=0;

i++;

}

SBUF='-'; //发送结束字符

while(TI==0);

TI=0; i=0; //i清0,为接收作准备

while(RI==0);//接收应答

RI=0;

recdata[i]=SBUF;

while(recdata[i]!=‘-’)

//传完后,应答A机并显示收到的字符串

{

i++;

while(RI==0);//接收应答

RI=0;

recdata[i]=SBUF;

} recdata[i]=‘\0’;

Lcd_display(0x40,recdata); //第2行显示

delay(200);

//延时200 ms后,继续以上A机和B机的握手过程

}

}

//*************主函数*****************//voidmain(void)

{

Lcd_initialize();

Lcd_display(0x00,“Awelcomeyou!”);

//第1行显示欢迎字符

serial();

}【例5-3】从机B的源程序。

#include<reg51.h>

#defineucharunsignedchar

sbitled=P2^3; //定义LED引脚,用于串口通讯指示

ucharrecdata[16]=“”;

//定义一个长度为16的空串,用于存放接收字符显示

uchartrdata[16]="FromB:slave_1!";

voidLcd_initialize(void);

voidLcd_display(ucharaddr,uchar*str); //LCD显示函数//*************串口通信函数*****************//

//单片机(A机)发送一字符串:"FromA:hjk!";

//本单片机(B机)接收,接收完成后在液晶屏中显示"FromA:hjk!",并回送"FromB:slave_1!",

//同时用LED灯来掼示传送时间(灭灯时间即回送时间)

//当接收到B机传送过来的"slave_1!"后在液晶屏中显示出来。

//然后,间隔200 ms后再循环以上过程

voidserial(void)

{ uchari=0;

TMOD=0x20;

//设置波特率为9600的定时器1方式和初值

TL1=0xfd;TH1=0xfd;

SCON=0xd8;PCON=0x00;

//设置串行口方式3,允许接收,TB8置1

TR1=1;

while(1)

{

while(RI==0);

RI=0;

recdata[i]=SBUF;

if(recdata[i]=='-') //传完后,应答A机并显示收到的字符串

{ led=0;//以LED指示A机传送完毕

recdata[i]=‘\0’;

Lcd_display(0x40,recdata); //第2行显示

i=0;

//此处i清0,为应答作准备

while(trdata[i]!='\0')

{

SBUF=trdata[i];

while(TI==0);

TI=0;

i++;

} SBUF=‘-’; //发送结束字符

while(TI==0);

TI=0;

led=1; //以LED指示B机应答完毕

i=0;

//此处i清0,为下一次接收作准备

}

else i++; }

}

voidmain()

{

Lcd_initialize();

Lcd_display(0x00,"Bwelcomeyou!"); //第1行显示欢迎字符

serial(); //串口接收并显示函数

}4.仿真结果

启动仿真,仿真结果如图5-16和图5-17所示。图5-16A机仿真结果图5-17B机仿真结果5.3.4多机通信设计

1.设计要求

用三个MCS-51单片机进行多机通信设计。具体要求如下:

(1)一个主机MasterA,两个从机:Slave_1B和Slave_2C。

(2)主机与从机的通信过程按以下四个步骤进行。这四个步骤间的延时设定为0.5 s。

(3)在多机通信前,主机和从机均显示欢迎信息。

2.设计说明

由主机控制的多机通信可按照以下协议进行:

(1)首先使所有从机的SM2位置1,即使所有从机处于只接收地址帧的状态。

(2)主机先发送一个地址帧,其中8位为地址,第9位为地址/数据帧的标志位,该位置为1表示该帧为地址帧。

(3)从机接收到地址帧后,各自将其接收到的地址与本从机的地址比较。

(4)主机发送完地址帧后,就可以发送数据帧,即将发送帧的第9位置为0。

(5)在第(3)步中与地址帧有相同地址的从机,由于其SM2=0,所以可以接收主机发送的数据帧,并根据数据帧的指示完成相应的操作。

(6)从机按照主机的指示,完成相应的操作后,则重新回到监听地址状态。

(7)主机在第(4)步发送完数据后,在从机的配合下,主机完成相应的功能操作。图5-18中仅列出了从机B的程序流程图,事实上,其他从机的程序流程图可与从机B的完全一致,各从机之间的区别是每个从机向主机发送的信息可能不同,接收到主机的信息后对数据的处理过程也可能不同。图5-18多机通信程序流程图

3.设计源码

主机A、两个从机B和C均单独编写程序文件,源程序分别见例5-4、例5-5和例5-6。

【例5-4】

主机A的源程序。

#include<reg51.h>

#defineucharunsignedchar

#defineuintunsignedint

#defineslave2

//定义一个长度为16的空串,用于存放接收字符显示

ucharrecdata[16]="";

uchartrdata[16]="FromA:master!";voidLcd_initialize(void);

voidLcd_display(ucharaddr,uchar*str);

voidmaster(ucharslave_addr,ucharcom);

voiddelay(ucharx);

//*************串口初始化函数*****************//

voidserial_init(void)

{ TMOD=0x20;

//T/C1定义为方式2

TL1=0xfd;TH1=0xfd;

//设置波特率为9600的定时器1方式和初值

PCON=0x00;

TR1=1;//T/C1运行,产生串口波特率

SCON=0xf8;

//设置串行口方式3,多机通讯方式,允许接收,TB8=1

}

//*************串口通信函数——多机通信*****************//

voidmaster(ucharslave_addr,ucharcom)

{ #defineBN16

uchari=0,p=0;

TB8=1;

SBUF=slave_addr;//发送从机地址

while(TI==0);TI=0;

TB8=0; //地址标志清0

SBUF=com;//发送命令:1为发送,2为接收

while(TI==0);TI=0;

if(com==0x01) //主机发送

{ p=0; //清校验和

for(i=0;i<BN;i++)

{

SBUF=trdata[i];//发送一数据

p+=trdata[i]; //求校验和

while(TI==0);TI=0;

}

SBUF=p; //发送校验和

while(TI==0);TI=0;

} else //主机接收

{

p=0;

for(i=0;i<BN;i++)

//接收数据并求校验和

{

while(RI==0);RI=0;

recdata[i]=SBUF;

p+=recdata[i];

} while(RI==0);RI=0; //接收校验字

if(p==SBUF)

//校验和正确时显示数据,否则显示接收错误

{

Lcd_display(0x40,recdata);

//显示接收到的数据

}

elseLcd_display(0x40,"Error!");

}

}//**************调用函数,实现多机通信******************//

voidserial_M(void)

{

//下面几行可证明多机通信功能正常

master(1,0x01); delay(250);

master(2,0x01); delay(250);

master(1,0x02);

delay(250); delay(250);

master(2,0x02);

delay(250); delay(250);

}//**************主函数******************//

voidmain(void)

{

Lcd_initialize();

Lcd_display(0x00,"Awelcomeyou!"); //第1行显示欢迎信息

serial_init();

serial_M();

}【例5-5】

从机B实现多机通信的源程序。

#include<reg51.h>

#defineucharunsignedchar

#defineslave_addr1

#defineBN16

sbitled=P2^3;

//定义LED引脚,用于串口通信指示ucharrecdata[16]=""; //定义一个长度为16的空串,用于存放接收字符显示

uchartrdata[16]="FromB:slave_1!";

voidLcd_initialize(void);

voidLcd_display(ucharaddr,uchar*str); //LCD显示函数

voidserial_M(void);

//*************串口通信函数——多机通信*****************//

voidserial_M(void)

{ TMOD=0x20;//T/C1定义为方式2

TL1=0xfd;TH1=0xfd;

//设置波特率为9600的定时器1方式和初值

SCON=0xf8;PCON=0x00;

//设置串行口方式3,多机通信方式,允许接收,

//TB8置1(为发送作准备)

TR1=1; //T/C1运行,产生串口波特率

EA=1;ES=1;//开串口中断

while(1){}

}//**********中断处理函数*****************//

//仅用一次串口中断,然后使用查询方式完成串口通信

voidSerial_Int(void)interrupt4using1

{

staticucharp=0,i=0;

RI=0;ES=0; //关中断

if(RB8==1)

{ if(SBUF==slave_addr)

{

SM2=0;

}

Else

{ES=1;return;} //非本机地址继续监听

}

while(RI==0);RI=0; if(SBUF==0x01) //主机发送,从机接收

{

p=0;

for(i=0;i<BN;i++) //接收数据并求校验和

{

while(RI==0);RI=0;

recdata[i]=SBUF;

p+=recdata[i];

} while(RI==0);RI=0; //接收校验字

if(p==SBUF) //校验和正确时显示数据,否则显示接收错误

{

Lcd_display(0x40,recdata); //显示接收到的数据

}

elseLcd_display(0x40,"Error!");

}

else

{ p=0; //清校验和

for(i=0;i<BN;i++)

{

SBUF=trdata[i];//发送一个数据

p+=trdata[i];//求校验和

while(TI==0);TI=0;

}

SBUF=p; //发送校验和

while(TI==0);TI=0;

} SM2=1;ES=1; //开中断

}

voidmain(void)

{

Lcd_initialize();

Lcd_display(0x00,“Bwelcomeyou!”);

//第1行显示欢迎字符

serial_M(); //多机通信

}【例5-6】

从机C实现多机通信的源程序。

#include<reg51.h>

#defineucharunsignedchar

#defineslave_addr2

#defineBN16 sbitled=P2^3; //定义LED引脚,用于串口通信指示

ucharrecdata[16]=“

”;

//定义一个长度为16的空串,用于存放接收字符显示

uchartrdata[16]="FromC:slave_2!";

voidLcd_initialize(void);

voidLcd_display(ucharaddr,uchar*str); //LCD显示函数

voidserial_M(void);//*************串口通信函数——多机通信*****************//

voidserial_M(void)

{

TMOD=0x20; //T/C1定义为方式2

TL1=0xfd;TH1=0xfd;

//设置波特率为9600的定时器1方式和初值

// SCON=0xf0; PCON=0x00;

//设置串行口方式3,多机通信方式,允许接收

SCON=0xf8;PCON=0x00;

//设置串行口方式3,多机通信方式,允许接收, TR1=1; //T/C1运行,产生串口波特率

EA=1;ES=1;//开串口中断

while(1){}

}

//**********中断处理函数*****************//

//仅用一次串口中断,然后使用查询方式完成串口通信

voidSerial_Int(void)interrupt4using1

{ staticucharp=0,i=0;

RI=0;ES=0; //关中断

if(RB8==1)

{

if(SBUF==slave_addr)

{

SM2=0;

}

else

{ES=1;return;}

//非本机地址继续监听

} while(RI==0);RI=0;

if(SBUF==0x01) //主机发送,从机接收

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论