C51学习笔记 6.串口

C51 6.串口

前言

C51内部自带UART(通用异步收发器),可实现单片机的串口通信。

祝愉快

1.硬件电路(UART)

在这里插入图片描述

  • UART为全双工、异步、点对点通信
  • 发送端TXD,接收端RXD
  • TXD和RXD要交叉连接
  • 单向传输数据时可以只用一根线通信
  • 当电平标准不一致时,要加电平转换芯片(C51标准为TTL)

2.串口模式图

串口

C51手册的图

在这里插入图片描述

我们简化为如下

在这里插入图片描述

  • 我们要打开定时器1,当定时器1的TH1、TL1溢出时,我们推出TI或RI。
  • SBUF为串口数据缓存寄存器,物理上是两个独立的寄存器,但是占用相同的地址。
  • 写操作时,写入的是发送寄存器。
  • 读操作时,读取的是接收寄存器。
  • 我们其实操作的就是SBUF寄存器。

串口和中断系统

在这里插入图片描述

打开中断就可以了。

3.串口相关寄存器

在这里插入图片描述

SCON

在这里插入图片描述

  • SM0/FE:为1时,用于帧错误检测。当检测到一个无效停止位时,通过UART接收器设置该位。必须由软件清零。为0时,和SM1一起指定串行通信的工作方式

  • 其中SM0、SM1按如下组合确定串口的工作模式,我们常用方式1

  • 在这里插入图片描述

  • SM2:允许方式2或方式3多机通信控制位。

  • REN:允许/禁止串行接收控制位。由软件置位,1为允许,可启动串行接收器RxD,开始接收数据。0则为禁止。

  • TB8:在方式2或方式3,它为要发送的第9位数据,按需要由软件置位或清零。

  • RB8:在方式2或方式3,是接收到的第9位数据。在方式1,若SM2=0,则RB8是接收到的停止位。方式0不用RB8。

  • TI:发送中断请求标志位。在方式0,当串口发送数据第8位结束时,由内部硬件自动置位,即TI=1,向主机请求中断,响应中断后必须用软件复位,即TI=0。在其他方式中,则在停止位开始发送时由内部硬件置位,必须用软件复位

  • RI:接收中断请求标志位。在方式0,当串口发送数据第8位结束时,由内部硬件自动置位,即RI=1,向主机请求中断,响应中断后必须用软件复位,即RI=0。在其他方式中,则在停止位的中间时刻由内部硬件置位,必须用软件复位。

    在这里插入图片描述

PCON

在这里插入图片描述

SBUF

在这里插入图片描述

SADEN和SADDR

  • SADEN为从机地址掩模寄存器(地址为B9H,复位值为00H)
  • SADDR是从机地址寄存器(地址为A9H,复位值为00H)

4.串口工作模式1:8位UART 波特率可变

当SM0、SM1为“01”时,串行通信以模式1工作。此模式为UART格式,一帧信息为10位:1位起始位,8位数据位(低位在先)和1位停止位,波特率可变。

TxD为发送信息,RxD为接收端接收信息,串口为全双工接受/发送串行口。

时序图

在这里插入图片描述

5.C代码

发数据

#include <REGX52.H>

/**
  * @brief  串口初始化,4800bps@12.000MHz
  * @param  无
  * @retval 无
  */
void UART_Init()
{
	SCON=0x40;		//配置串口 0100 0000
	PCON |= 0x80;	//配置串口 10xx xxxx
	TMOD &= 0x0F;		//设置定时器模式
	TMOD |= 0x20;		//设置定时器模式
	TL1 = 0xF3;		//设定定时初值
	TH1 = 0xF3;		//设定定时器重装值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
}

/**
  * @brief  串口发送一个字节数据
  * @param  Byte 要发送的一个字节数据
  * @retval 无
  */
void UART_SendByte(unsigned char Byte)
{
	SBUF=Byte;		//对SBUF写操作
	while(TI==0);	//保持TI为0
	TI=0;			//TI被硬件置1了,我们手动置0
}

收数据

#include <REGX52.H>
#include "Delay.h"
#include "UART.h"

void main()
{
	UART_Init();		//串口初始化
	while(1)
	{
		
	}
}

void UART_Routine() interrupt 4 //中断号4
{
	if(RI==1)					//如果接收标志位为1,接收到了数据
	{
		P2=~SBUF;				//读取数据,取反后输出到LED  对SBUF读操作
		UART_SendByte(SBUF);	//将受到的数据发回串口
		RI=0;					//接收标志位清0             接收完成后RI被硬件置1,我们手动对RI清0
	}
}

子函数

#include <REGX52.H>

/**
  * @brief  串口初始化,4800bps@12.000MHz
  * @param  无
  * @retval 无
  */
void UART_Init()
{
	SCON=0x50;
	PCON |= 0x80;
	TMOD &= 0x0F;		//设置定时器模式
	TMOD |= 0x20;		//设置定时器模式
	TL1 = 0xF3;		//设定定时初值
	TH1 = 0xF3;		//设定定时器重装值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
	EA=1;
	ES=1;
}

/**
  * @brief  串口发送一个字节数据
  * @param  Byte 要发送的一个字节数据
  * @retval 无
  */
void UART_SendByte(unsigned char Byte)
{
	SBUF=Byte;
	while(TI==0);
	TI=0;
}

/*串口中断函数模板
void UART_Routine() interrupt 4
{
	if(RI==1)
	{
		
		RI=0;
	}
}
*/

总结

UART内容很多,想更加了解可以去看看手册。

本文基本没讲时序图,有兴趣可以自行了解。

C语言层面比硬件方面简单很多,我们关注TI、RI,然后对SBUF进行读写就可以了。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值