MCS-51串行口具有两条独立的数据线:发送端TXD、接收端RXD,允许数据同时往两个相反的方向传输。一般通信时发送数据由TXD端输出,接收数据由RXD端输入。
一、串行口的控制寄存器
MCS-51单片机串行口是由缓冲器SBUF、移位寄存器、串行口控制寄存器SCON、电源控制寄存器PCON及波特率发生器T1组成。
1.串行口数据缓冲器SBUF
MCS-51单片机内的串行接口部分,具有两个物理上独立的缓冲器:发送缓冲器和接收缓冲器,以便能以全双工的方式进行通信。串行口的接收由移位寄存器和接收缓冲器构成双缓冲结构,能避免在接收数据过程中出现帧重叠。发送时因为CPU是主动的,不会发生帧重叠错误,所以发送结构是单缓冲的。
在逻辑上,串行口的缓冲器只有一个,它既表示接收缓冲器,也表示发送缓冲器。两者共用一个寄存器名SBUF,共用一个地址99H。
即:在完成串行口初始化后,发送数据时,采用MOV SBUF,A指令,将要发送的数据输入SBUF,则CPU自动启动和完成串行数据的输出;接收数据时,采用MOV A,SBUF指令,CPU就自动将接收到的数据从SBUF中读出。
2.串行口控制寄存器SCON
串行口控制寄存器SCON包含:串行口工作方式选择位、接收发送控制位、以及串行口状态标志位。其格式如下:
D7 |
D6 |
D5 |
D4 |
D3 |
D2 |
D1 |
D0 |
SM0 |
SM1 |
SM2 |
REN |
TB8 |
RB8 |
TI |
RI |
①SM0 SM1(SCON.7、SCON.6):串行口的工作方式选择位,其编码见表6-1。
表6-1 串行口的工作方式
SM0 SM1 SM1 |
工作方式 |
说 明 |
波特率 |
0 0 |
方式0 |
同步移位寄存器 |
fosc/12 |
0 1 |
方式1 |
10位异步收发 |
由定时器控制 |
1 0 |
方式2 |
11位异步收发 |
fosc/32或fosc/64 |
1 1 |
方式3 |
11位异步收发 |
由定时器控制 |
②SM2(SCON.5):多机通信控制位。在方式2或方式3中,若SM2=1,则只有当接收到的第9位数据(RB8)为1时,才能将接收到的数据送入SBUF,并使接收中断标志RI置位向CPU申请中断,否则数据丢失;若SM2=0,则不论接收到的第9位数据为1还是为0,都将会把前8位数据装入SBUF中,并使接收中断标志RI置位向CPU申请中断。在方式1,如SM2=1,则只有收到有效的停止位时才会使RI置位。在方式0时,SM2必须为0。
③REN(SCON.4):串行口接收允许位。由软件置位以允许接收,由软件清0来禁止接收。
④TB8(SCON.3):在方式2和方式3中为发送的第9位数据。在多机通信中,常以该位的状态来表示主机发送的是地址还是数据。通常协议规定:TB8为“0”表示主机发送的是数据,为“1”表示发送的是地址。
⑤RB8(SCON.2):在方式2和方式3中为接收到的第9位数据。它和SM2、TB8一起用于通信控制。
⑥TI(SCON.1):发送中断标志。由硬件在方式0串行发送第8位结束时置位,或在其他方式串行发送停止位的开始时置位,必须由软件清“0”。
⑦RI(SCON.0):接收中断标志。由硬件在方式0串行接收到第8位结束时置位,或在其他方式串行接收到停止位的中间时置位,必须由软件清“0”。
3.电源控制寄存器PCON
电源控制寄存器PCON的格式如下:
D7 |
D6 |
D5 |
D4 |
D3 |
D2 |
D1 |
D0 |
SMOD |
|
|
|
|
|
|
|
D7位SMOD是串行口波特率倍增位。SMOD为1时,串行口工作方式1、方式2、方式3的波特率加倍。具体值见各种工作方式下的波特率计算公式。
二、串行口的工作方式
(一)方式0
方式0为同步移位寄存器输入输出方式。其工作方法是:串行数据通过RXD端输入/输出,TXD则用于输出移位时钟脉冲。方式0时,收发的数据为8位,低位在前,高位在后。波特率固定为fosc/12,其中fosc为单片机的晶振频率。
图6-6 方式0发送、接收电路 a) 发送接口电路 b) 接收接口电路 |
利用此工作方式,可以在串行口外接移位寄存器以扩展I/O接口,也可以外接串行同步输入输出的设备。图6-6所示为串行口外接一片移位寄存器74LS164的输出接口电路和74LS165的输入接口电路的情况。
数据的发送是以写SBUF寄存器指令开始的,8位数据由低位至高位顺序由RXD端输出,同时由TXD端输出移位脉冲,且每个脉冲输出一位数据。8位数据输出结束时TI被置位。在图6-6a所示串行口输出电路中,74LS164为一串入并出的移位寄存器,据此通过串行口方式0发送数据可编程如下:
WAIT: |
MOV SETB MOV MOV JNB CLR CLR |
SCON,#00H P1.0 A,#DATA SBUF,A TI,WAIT TI P1.0 |
;选通74LS164 ;置要发送的数据 ;数据写入SBUF并启动发送 ;等待一个字节数据发送完 ;清除TI ;关闭74LS164 |
图6-6 b是串行口在方式0下利用并入串出芯片74LS165来完成数据的接收。接收是在REN=1和RI=0同时满足时开始的,在移位时钟同步下,将数据字节的低位至高位一位一位地接收下来并装入SBUF中,结束时RI置位。
(二)方式1
串行接口工作于方式1时,被定义为10位的异步通信接口,即传送一帧信息为10位。一位起始位“0”,8位数据位(先低位后高位),一位停止位“1”。其中起始位和停止位是在发送时自动插入的。
串行接口以方式1发送时,数据由TXD端输出。CPU执行一条数据写入发送缓冲器SBUF的指令(即:MOV SBUF,A指令),将数据字节写入SBUF后,便启动串行口发送,发送完一帧信息,发送中断标志TI置“1”。
方式1的波特率是可变的,可由以下公式计算得到:
方式1波特率=2SMOD·(定时器1的溢出率)/32
(三)方式2和方式3
串行接口工作于方式2和方式3时,被定义为11位的异步通信接口,即传送一帧信息为11位。一位起始位“0”,8位数据位(从低位至高位)、一位附加的第9位数据(可程控为1或0),一位停止位“1”。其中起始位和停止位是在发送时自动插入的。
方式2或方式3发送时,数据由TXD端输出,发送一帧信息为11位,附加的第9位数据就是SCON中的TB8,CPU执行一条数据写入发送缓冲器SBUF的指令(即指令MOV SBUF,A),就启动串行口发送,发送完一帧信息,发送中断标志TI置位。
方式2和方式3的操作过程是一样的,所不同的是它们的波特率。
方式2波特率=2SMOD·fosc/64
方式3波特率=2SMOD·(定时器1的溢出率)/32
三、波特率的设置
MCS-51单片机串行口通信的波特率取决于串行口的工作方式。当串行口被定义为方式0时,其波特率固定等于 。当串行口被定义为方式2时,其波特率= ,即当SMOD=0时,波特率= ;当SMOD=1时,波特率= 。SMOD是PCON寄存器的最高位,通过软件可设置SMOD=0或l。因为PCON无位寻址功能,所以,要想改变SMOD的值,可通过执行以下指令来完成:
ANL PCON,#7FH ;使SMOD=0
ORL PCON,#80H ;使SMOD=1
当串行口被定义为方式1或方式3时,其波特率=2SMOD×定时器T/C1的溢出率/32。定时器T/C1的溢出率,取决于计数速率和定时器的预置值。下面说明T/C1溢出率的计算和波特率的设置方法。
1.T/C1溢出率的计算
在串行通信方式1和方式3下,使用定时器T/C1作为波特率发生器。T/C1可以工作于方式0、方式1和方式2,其中方式2为自动装入时间常数的8位定时器,使用时只需进行初始化,不需要安排中断服务程序重装时间常数,因而在用T/C1作波特率发生器时,常使其工作于方式2。
前面我们介绍过定时器定时时间的计算方法,同样,我们设X为时间常数即定时器的初值; 为晶振频率,当定时器T/C1工作于方式2时,则有:
溢出周期=(28-X)×12/
溢出率=1/溢出周期= /[12(28-X)]
2.波特率的设置
由上述可得,当串行口工作于方式1或方式3、定时器T/C1工作于方式2时
波特率=2SMOD×定时器T/C1溢出率/32
=2SMOD× /[32×12(28-X)]
当 =6MHz,T/C1工作于方式2时,波特率的范围为61.04~31250b/s。
由上式可以看出,当X=255时,波特率为最高。如 =12MHz,SMOD=0,则波特率为31.25Kb/s,若SMOD=1,则波特率为62.5Kb/s。这是 =12MHz时波特率的上限。若需要更高的波特率,则需要提高主振频率 。
在实际应用中,一般是先按照所要求的通信波特率设定SMOD,然后再算出T/C1的时间常数。即:
X=28-2SMOD× /(384×波特率)
例如,某8051单片机控制系统,主振频率为12MHz,要求串行口发送数据为8位、波特率为1200b/s,编写串行口的初始化程序。
我们设SMOD=1,则T/C1的时间常数X的值为:
X=28-2SMOD× /(384×波特率)
=256-2×12×106/(384×1200)
=256-52.08=203.92≈0CCH
初始化程序为:
MOV SCON,#50H ;串行口工作于方式1
ORL PCON,#80H ;SMOD=1
MOV TMOD,#20H ;T1工作于方式2,定时方式
MOV TH1,#0CCH ;设置时间常数初值
MOV TL1,#0CCH
SETB TR1 ;启动T/C1
再如,要求串行通信波特率为2400b/s,假设 =6MHz,SMOD=1,则T/C1的时间常数为:
X=28-21×6×106/(384×2400)
=242.98≈243=F3H
定时器T/C1和串行口的初始化程序如下:
MOV TMOD,#20H ;设T/C1为方式2定时
MOV THl,#0F3H ;置时间常数
MOV TLl,#0F3H
SETB TRl ;启动T/C1
ORL PCON,#80H ;SMOD=1
MOV SCON,#50H ;设串行口方式1
执行上面的程序后,即可使串行口工作于方式1,波特率为2400b/s。
需要指出的是,在波特率的设置中,SMOD位数值的选择直接影响着波特率的精确度。以上例所用数据来说明,波特率=2400b/s, =6MHz,这时SMOD可以选为1或0。由于对SMOD位数值的不同选择,所产生的波特率误差是不同的。
1)选择SMOD=1,由上面计算已得T/C1时间常数X=243,按此值可算得T/C1实际产生的波特率及误差为
波特率=2SMOD× /[2×12(28-X)]
=21× /[32×12(256-243)]
=2403.85b/s
波特率误差=(2403.85-2400)/2400=0.16%
2)选择SMOD=0,此时
X=28-20×6×106/(384×2400)=249.49≈249
由此值可以算出T/C1实际产生的波特率及误差为:
波特率=20×6×106/[32×12(256-249)]=2232.14b/s
波特率误差=(2400-2232.14)/2400=6.99%
上面的分析计算说明了SMOD值虽然可以任意选择,但在某些情况下它会使波特率产生误差。因而在波特率设置时,对SMOD值的选取也需要予以考虑。
表6-2列出了常用波特率的设置方法。
表6-2 常用波特率设置方法
波特率 /Hz |
/MHz |
SMOD |
定时器1 |
||
C/ |
方式 |
重新装入值 |
|||
方式0最大:1M 方式2最大:375k 方式1、3:62.5k 19.2k 9.6k 4.8k 2.4k 1.2k 110 |
12 12 12 11.0592 11.0592 11.0592 11.0592 11.0592 12 |
X 1 1 1 0 0 0 0 0 |
X X 0 0 0 0 0 0 0 |
X X 2 2 2 2 2 2 1 |
X X FFH FDH FDH FAH F4H E8H 0FEEH |