一.串口相关寄存器(只给出有用的位)

1.SCON控制寄存器

SFR name Address bit B7 B6 B5 B4 B3 B2 B1 B0
SCON 98H name SM0/FE SM1 SM2 REN TB8 RB0 TI RI

SM0/FE:当PCON寄存器的SMOD0为0时,该位和SM1一起指定串行通信的工作方式。(由下表可见定时器0不能作为串口的波特率发生器

在这里插入图片描述

SM2:允许方式2或方式3多机通信控制位。(此不用)

REN:1—允许串行接收状态,可启动RxD,开始接收信息,0—禁止接收。

TB8:在方式2或3,存放发送的第9位数据。(此不用)

RB8:在方式2或3,存放接收的第9位数据。(此不用)

TI:发送中断请求标志位。发送数据结束置1,需要软件清0.

RI:接收中断请求标志位。接收数据结束置1,需要软件清0.

2.PCON电源控制寄存器(不可位寻址)

SFR name Address bit B7 B6 B5 B4 B3 B2 B1 B0
PCON 87H name SMOD SMOD0

SMOD: 波特率选择位。1—串行通信方式1、2、3的波特率加倍,0—各工作方式的波特率不加倍。

SMOD0:帧错误检测有效控制位。用于控制SCON寄存器B7位的功能。

3.SBUF数据缓冲寄存器

实际是2个缓冲器。向写SBUF写入数据后,数据会自动发送。有数据接收时会存在读SBUF中,可从读SBUF中获取接收到的数据。

4.AUXR辅助寄存器

SFR name Address bit B7 B6 B5 B4 B3 B2 B1 B0
AUXR 8EH name T1x12 UART_M0x6 T2R

S1ST2

T1x12:0—定时器1工作于12T模式,1—定时器1工作于1T模式。

UART_M0x6:0—串口1模式0的速度是12分频,1—串口1模式0的速度是2分频。

T2R:0—关闭定时器2,1—打开定时器2。

S1ST2:0—选择定时器1为串口1的波特率发生器,1—选择定时器2作为串口1的波特率发生器。

5.串行口1中断寄存器位ES

SFR name Address bit B7 B6 B5 B4 B3 B2 B1 B0
IE A8H name EA

ES

EA:总中断控制位。0—不允许,1—允许。

ES:串口1中断控制位。0—不允许,1—允许。

6.AUXR1(P_SW1)将串口1进行切换的寄存器

SFR name Address bit B7 B6 B5 B4 B3 B2 B1 B0
AUXR1 A2H name S1_S1 S1_S0

在这里插入图片描述

二.代码

//串口1初始化函数,可由软件自动生成
void UartInit(void)		//9600bps@11.0592MHz
{
	PCON &= 0x7F;		//波特率不倍速
	SCON = 0x50;		//8位数据,可变波特率,打开接收
	AUXR |= 0x40;		//定时器1时钟为Fosc,即1T
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//清除定时器1模式位
	TMOD |= 0x20;		//设定定时器1为8位自动重装方式
	TL1 = 0xDC;		//设定定时初值
	TH1 = 0xDC;		//设定定时器重装值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
}

//发送一个字节数据
void SendData(unsigned char dat)
{
	SBUF=dat;	//把要发送的数据存入写SBUF
	while(TI == 0);  //等待发送标志位置1
	TI = 0;
}

//发送字符串,以'\0'形式结尾
void SendString(unsigned char *s)
{
    while (*s!='\0')              //检查是否到结尾
    {
        SendData(*s++);     //地址递增进行逐个发送
    }
}

void main()
{
	unsigned char *str;
	EA=1;//打开总中断
	ES=1;//打开串口1中断
	while(1)
	{
		sprintf(str,"%d%d",20,20);	//变为字符串存入str
		SendString(str);	//串口1发送字符串
	};
}

//串口1中断,用于检测是否有数据接收到
void usart1_interrupt(void) interrupt 4
{
	unsigned char rec_da;
	TI=0;	//发送标志位清零
	if(RI==1)	//确认是接收到数据
	{
		RI=0;	//接收标志位清零
		rec_da=SBUF;	//读取接收到的数据
	}
}