【STC89C51单片机】串口通信

串口简介

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×(256TH1)晶振频率)
其中,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.0592MHz
	AUXR = 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.0592MHz
	AUXR = 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");
		
	}
}

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-18 14:44:02       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-18 14:44:02       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-18 14:44:02       58 阅读
  4. Python语言-面向对象

    2024-07-18 14:44:02       69 阅读

热门阅读

  1. 计算机视觉篇5 图像的位置--边框

    2024-07-18 14:44:02       18 阅读
  2. 大龄程序员的出路在哪里?

    2024-07-18 14:44:02       23 阅读
  3. [ptrade交易实战] 第十六篇 融资融券查询类函数!

    2024-07-18 14:44:02       25 阅读
  4. 项目随笔【环境变量的获取】

    2024-07-18 14:44:02       21 阅读
  5. 15.FreeRTOS_资源管理

    2024-07-18 14:44:02       23 阅读
  6. 牛奶供应(三)

    2024-07-18 14:44:02       17 阅读
  7. 正则表达式

    2024-07-18 14:44:02       22 阅读
  8. AI发展下的伦理挑战,应当如何应对?

    2024-07-18 14:44:02       18 阅读
  9. SDF学习笔记整理

    2024-07-18 14:44:02       24 阅读
  10. 24/07/18数据结构(7.1220)队列实现

    2024-07-18 14:44:02       22 阅读