STC89C52单片机串口通信以及代码演示

目录

串口介绍

硬件电路

电平标准

常见通讯接口比较

51单片机的UART

串口参数及时序图

串口通信流程图

串口相关寄存器

波特率的计算方法

中断模式以及寄存器的配置

数据显示模式

 代码示例(串口与电脑互发数据)


串口介绍

串口是一种应用十分广泛的通讯接口,串口成本低、容易使用、通信线路简单,可实现两个设备的互相通信。

单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信,极大的扩展了单片机的应用范围,增强了单片机系统的硬件实力。

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

硬件电路

简单双向串口通信有两根通信线(发送端TXD和接收端RXD)

TXD与RXD要交叉连接

当只需单向的数据传输时,可以直接一根通信线

当电平标准不一致时,需要加电平转换芯片

下图是以前的投影仪的插口线脚分布图,可以看的也用了TXD来发送数据,RXD来接受数据

电平标准

电平标准是数据1和数据0的表达方式,是传输线缆中人为规定的电压与数据的对应关系,串口常用的电平标准有如下三种:

TTL电平:+5V表示1,0V表示0

RS232电平:-3~-15V表示1,+3~+15V表示0

RS485电平:两线压差+2~+6V表示1,-2~-6V表示0(差分信号)

注意这里单片机用的是TTL电平,而计算机用的是RS232电平,所以在单片机与电脑进行串口通信的时候要加电平转换芯片

常见通讯接口比较

全双工:通信双方可以在同一时刻互相传输数据

半双工:通信双方可以互相传输数据,但必须分时复用一根数据线

单工:通信只能有一方发送到另一方,不能反向传输

异步:通信双方各自约定通信速率

同步:通信双方靠一根时钟线来约定通信速率

总线:连接各个设备的数据传输线路(类似于一条马路,把路边各住户连接起来,使住户可以相互交流)

51单片机的UART

串口参数及时序图

波特率:串口通信的速率(发送和接收各数据位的间隔时间)

检验位:用于数据验证(九位数据模式时的最后一位,RB8/TB8)

停止位:用于数据帧间隔

串口通信流程图

看串口模式图我们软件在进行编程的时候要注意:

SUBF(数据缓存器),TI(数据发送标志位),RI(数据接受标志位)的配置要求

以及T1溢出率的配置(TH1,TL1初值),SMOD置0时为正常波特率,置1时波特率加倍

串口相关寄存器

这里还是为了尽可能的全面,所以在手册截的图。

 补充说明一下,波特率的计算方法:

在图上的寄存器SCON的配置中也可以看出来。1,是看SMOD的配置为1那么波特率加倍。2,其次是定时器1的溢出率,计算方法是周期的倒数。

下面举波特率为4800的计算方法(也是我们下面的代码里面的定时器1配置的)

设T=13us,定时器1的溢出率=1/T=0.0769230769230769,为使定时器误差小,这里的SMOD的配置为1,所以最后,波特率=(1/T)x(1/16)x1000000=4,807.692307692308 约等于4800

中断模式以及寄存器的配置

串口中断位要打开,而定时器1的中断就不用开了(溢出后不用进行中断执行其他操作,计时器只是提供稳定的波特率)

这里有个小错误:上面的为定时器0,下面的是定时器1

数据显示模式

HEX模式/十六进制模式/二进制模式:以原始数据的形式显示

文本模式/字符模式:以原始数据编码后的形式显示(即ASCLL代码编译以后)

 代码示例(串口与电脑互发数据)

主函数:

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

unsigned char Sec;

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

void UART_Routine() interrupt 4
{
	if(RI==1)	//如果接收到数据,硬件自动将标志位RI置1,表示接收到了电脑发送的数据
	{
		P2=SBUF;				//读取SBUF数据,取反后输出到LED
		UART_SendByte(SBUF);//将受到的数据发回串口(实现单片机向电脑发送数据)
		RI=0;					  //按照手册RI需要手动置0
	}
}

SUBF输入函数:

#include <REGX52.H>

void UART_Init()
{
	SCON = 0x50;    //工作方式1,其中的REN为1,允许接收
	PCON |= 0x80;   //为了减少误差波特率加倍
	TMOD &= 0x0F;		//设置定时器1模式
	TMOD |= 0x20;		//设置定时器1模式
	TL1 = 0xF3;		  //设定定时初值
	TH1 = 0xF3;		  //设定定时器重装值
	ET1 = 0;		    //禁止定时器1中断
	TR1 = 1;		    //启动定时器1

    ES=1;           //设置接收发送中断
	EA=1;


}

void UART_SendByte(unsigned char Byte)
{
	SBUF=Byte;   //将SBUF数据赋值
	while(TI==0);//if(TI==1) {TI=0;}在停止位后硬件自动将TI置1,按照手册,这里要手动置0
	TI=0;
}

posted @ 2022-04-09 17:36  爱吃炸鸡的小猪  阅读(1356)  评论(0编辑  收藏  举报