接下来我以一段代码来详细分解串口的配置:
***************************************************************************************/
#include "reg52.h" //此文件中定义了单片机的一些特殊功能寄存器
typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;
/*******************************************************************************
* 函 数 名 : UsartInit
* 函数功能 :串口初始化
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void UsartInit()
{
TMOD|=0X20;//选择为定时器1模式,工作方式2
TH1=0X3F;//设定定时器1的初值
TL1=0X3F;
PCON=0X80;//设置波特率倍增位
TR1=1;//打开定时器
SCON=0x50;//设置scon特殊功能寄存器
ES=1;//打开串口中断
EA=1;//打开串口总中断
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
void UsartInit(); //定时器1初始化
while(1);
}
/*******************************************************************************
* 函 数 名 : void Usart() interrupt 4
* 函数功能 : 中断函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Usart() interrupt 4
{
u8 receiveData;//定义一个变量,用来保存接收的数据(从pc发给单片机的)
receiveData=SBUF;//接收的数据默认是保存在SBUF里的,这里把sbuf里的数据转移过来
RI=0;//单片机接收完pc发的数据后(或者说接收到停止位的时候),内部硬件会将ri会置1,
发生串行口中断,这里要用软件来进行清零(这里本来就是中断程序内部,
这里的ri已经本来变成1了,清0是为了下次再使用ri)。
SBUF=receiveData;//这里是把刚刚接收到的数据进行发送,
把数据重新放进sbuf(发送缓存寄存器)里去。
(ps:不是所有的程序都是这样的,这段程序的目的就是发一个数据马上接收一个数据,
用来验证串口通信的效果,实际工作中可能会对数据进行各种计算,
或者根本就不产生应答)
while(!TI);//判断发送是否完成,如果发送完成,ti被硬件置1,这个while循环结束
如果发送仍在继续,ti是0,这个while循环后面为1(真),循环继续,等待发送完成。
TI=0;//程序到达这里,必定是发送完成后,ti已经被变成1,此时就需要软件来清零,
这样下次才能继续使用。
}
这个可以简单得看作是一部分初始化串口的代码,
实际上是对各个参数进行配置选择,来设定串口如何使用,
代码上看这些寄存器的一些特定位如果是不同的状态(0或者1),那么该串口就有不同的功能,那么寄存器就会呈现不同的值,通过对几个关键的寄存器赋各种值,那么就可实现配置串口。

代码:
TMOD|=0X20;//选择为定时器1模式,工作方式2
这里的0x20可以看成是一串二进制代码0010 0000,它的具体配置内容如下:
1、工作方式寄存器TMOD
工作方式寄存器TMOD用于设置定时/计数器的工作方式,低四位用于T0,高四位用于T1。其格式如下:
GATE是门控位, GATE=0时,用于控制定时器的启动是否受外部中断源信号的影响。只要用软件使TCON中的TR0或TR1为1,就可以启动定时/计数器工作;GATA=1时,要用软件使TR0或TR1为1,同时外部中断引脚INT0/1也为高电平时,才能启动定时/计数器工作。即此时定时器的启动条件,加上了INT0/1引脚为高电平这一条件。 C/T :定时/计数模式选择位。C/T =0为定时模式;C/T =1为计数模式。 M1M0:工作方式设置位。定时/计数器有四种工作方式。
就这里来说:
tmod寄存器的的第7位gate设置为0,代表只要用软件使TCON中的TR0或TR1为1,就可以启动定时/计数器工作;
tmod寄存器的的第6位C/T 设置为0,代表选择为定时模式;
tmod寄存器的的第5、4位设置为10,代表选择为方式2;即8位自动重装载寄存器。
低四位用于T0,高四位用于T1,这里就是用高4位来设置了t1计时器,t0计时器没有使用,这里全部赋0;
于是把tmod寄存器赋值为0010 0000
2、计算t1的初值这里可以用小工具计算出来,然后直接把值赋给它,也可以直接把计算公式代码写出来计算一次值
这里的代码是:
TH1=0X3F;
TL1=0X3F;
t1初值就是用来定义波特率的
初值的计算可以看下面的资料:
tmod寄存器的的第7位smod设置为1,所以这个值为0x80
4、启动t1(计数器1)tr1=1
这里的内容就比较多了,见下
0x50=0101 0000
即:
sm0=0
sm1=1
sm2=0
ren=1
tb8=0
tb8=0
ti=0
ri=0
6、打开串口中断和总中断es=1
ea=1
补充:
SBUF是指串行口中的两个缓冲寄存器,一个是发送寄存器,一个是接收寄存器,在物理结构上是完全独立的,但地址是重叠的。它们都是字节寻址的寄存器,字节地址均为99H。
SBUF,全称:serial data buffer,中文名为串行数据缓冲器。这个重叠的地址靠读/写指令区分:串行发送数据时,CPU向SBUF写入数据,此时99H表示串行口的发送缓冲寄存器;串行接收数据时,CPU从SBUF读出数据,此时99H表示串行口的接收缓冲寄存器。
这个讲得比较好:
STC89C52_51单片机_串口配置_UART串口通信_hello_StarLee的博客-CSDN博客_stc89c51串口通信