【STC89C51单片机】串口通信
- 串口简介
- 1. 串口接线方式
- 2. 通信过程
- 相关寄存器
- 1. SBUF(Serial Buffer Register)
- 2. SCON(Serial Control Register)
- 3. PCON(Power Control Register)
- 4. TCON(Timer Control Register)
- 5. 串口波特率
- 代码示例
- 发送数据:
- 接收数据
- 相关寄存器配置**
- 完整代码
串口简介
STC89C51RC/RD+系列单片机内部集成有一个功能很强的全双工串行通信口,与传统8051单片机的串口完全兼容。设有2个互相独立的接收、发送缓冲器,可以同时发送和接收数据。发送缓冲器只能写入而不能读出,接收缓冲器只能读出而不能写入,,因而两个缓冲器可以共用一个地址码(99H)。两个缓冲器统称串行通信特殊功能存器SBUF
1. 串口接线方式
2. 通信过程
输入/输出数据缓冲器都叫做SBUF, 都用99H地址码,但是是两个独立的8位寄存器
代码体现为: 想要接收数据 char data = SBUF 想要发送数据 SBUF = data
UART是异步串行接口,通信双方使用时钟不同,因为双方硬件配置不同,但是需要约定通信速度,叫做波特率
相关寄存器
1. SBUF(Serial Buffer Register)
发送数据:写数据到SBUF,数据会从TXD引脚发送出去。
接收数据:当接收到的数据存储在SBUF,可以从SBUF读取数据。
2. SCON(Serial Control Register)
SCON寄存器用于控制串口的工作方式和状态。其位定义如下:
- SM0, SM1:选择串口的工作模式(Mode)
- 0 0:模式0,移位寄存器方式,波特率为定时器频率/12
- 0 1:模式1,8位UART,波特率可变
- 1 0:模式2,9位UART,波特率为定时器频率/32或/64
- 1 1:模式3,9位UART,波特率可变
- REN:允许接收(Receiver Enable)
- TB8:在模式2或3中使用的第9位发送数据
- RB8:在模式2或3中使用的第9位接收数据
- TI:发送中断标志(Transmit Interrupt Flag)
- RI:接收中断标志(Receive Interrupt Flag)
3. PCON(Power Control Register)
PCON寄存器的SMOD位用于控制串口波特率加倍:
- SMOD:当设为1时,串口波特率加倍。
4. TCON(Timer Control Register)
TCON寄存器中的位用于控制定时器/计数器的启动和中断。它们在串口通信中的作用主要是用于定时器的控制。
5. 串口波特率
波特率(Baud Rate)是串行通信中的一个重要参数,它定义了每秒钟传输的比特数。80C51的串口波特率可以通过定时器1的溢出率来控制。
波特率公式:
模式1和模式3
波特率 = 2 S M O D 32 × ( 晶振频率 12 × ( 256 − T H 1 ) ) \text{波特率}=\frac{2^{SMOD}}{32}\times\left(\frac{\text{晶振频率}}{12\times(256-TH1)}\right) 波特率=322SMOD×(12×(256−TH1)晶振频率)
其中,SMOD为PCON寄存器中的波特率加倍位,TH1为定时器1的高字节。
代码示例
发送数据:
void serial_send(char data) {SBUF = data; // 将数据写入SBUF寄存器while (!TI); // 等待发送完成TI = 0; // 清除发送中断标志
}
接收数据
char serial_receive() {while (!RI); // 等待接收完成RI = 0; // 清除接收中断标志return SBUF; // 读取接收的数据
}
相关寄存器配置**
void UartInit(void)
{//9600bps@11.0592MHzAUXR = 0x01;SCON = 0x50; //配置串口工作方式1,REN使能接收TMOD &= 0x0F;TMOD |= 0x20;//定时器1工作方式位8位自动重装 TH1 = 0xFD;TL1 = 0xFD;//9600波特率的初值TR1 = 1;//启动定时器 EA = 1;//开启总中断ES = 1;//开启串口中断
}
完整代码
#include "reg52.h"
sfr AUXR = 0x8e;void UartInit(void)
{//9600bps@11.0592MHzAUXR = 0x01;SCON = 0x50; //配置串口工作方式1,REN使能接收TMOD &= 0x0F;TMOD |= 0x20;//定时器1工作方式位8位自动重装 TH1 = 0xFD;TL1 = 0xFD;//9600波特率的初值TR1 = 1;//启动定时器 EA = 1;//开启总中断ES = 1;//开启串口中断
}
//发送数据
void serial_send(char data_mes) {SBUF = data_mes; // 将数据写入SBUF寄存器while (!TI); // 等待发送完成TI = 0; // 清除发送中断标志
}
//接收数据
char serial_receive() {while (!RI); // 等待接收完成RI = 0; // 清除接收中断标志return SBUF; // 读取接收的数据
}void serial_string(char* p) {while(*p != '\0'){serial_send(*p);p++;}}void Delay1000ms() //@11.0592MHz
{unsigned char i, j, k;i = 43;j = 6;k = 203;do{do{while (--k);} while (--j);} while (--i);
}void main()
{UartInit();while(1){Delay1000ms();serial_string("hello word\r\n");}
}