51单片机之UART

51单片机之UART

有关串口的相关概念看我的这篇博客

https://blog.csdn.net/qq_36461474/article/details/112626372

串口相关寄存器配置

与51单片机串口相关的寄存器有SBUF,SCON,PCON,以及与定时器1(T1)相关的寄存器。
SBUF:串口缓冲寄存器,物理上实际有两个寄存器,地址重叠而已,一个用来发送,一个用来接受。通过读或者写不同操作,才操作不同寄存器,设计在一起是为了简化操作。写入SBUF寄存器的数据会通过TXD引脚发送出去,从RXD引脚的数据可以通过读SBUF获取。
SCON:串口配置寄存器。

位序号D7D6D5D4D3D2D1D0
位符号SM0SM1SM2RENTB8RB8TIRI

SM0和SM1决定了串口的工作方式

SM0 SM1工作方式功能波特率
00方式08位同步移位寄存器晶振频率/12
01方式110位UART可变
10方式211位UART晶振频率/64或者晶振频率/32
11方式311位UART可变

10位UART是我们常用的模式,包括起始位,8个数据位(SBUF),一个停止位。11位UART多了一个数据位(TB8,发送数据的第八位;RB8,接受数据的第八位)。波特率可变是由于此时的定时器1 作为UART的时序信号,定时器1的溢出率决定了波特率,同时也受到PCON种的SMOD位的加倍影响。
SM2是多机通信控制位。只有用到了11位UART才会将SM2置1。
REN是接受使能,REN=1时,允许接收,REN=0时,禁止接收。
TI和RI分别是发送和接受中断标志位,当完成一次发送或者接收会将相应的标志位硬件置1,必须要软件清“0”。当设置了串口中断,还会进入中断函数。注意这两者会进入同一个中断函数,注意判断标志位来区别到底是放松中断还是软件中断。
详细信息移步百度

PCON:电源控制寄存器,其实只有最高位SMOD对串口有影响,SMOD=1,波特率加倍,SMOD=0,波特率不加倍。

T1相关寄存器的配置:使用可变波特率,T1一般用8位自动重装载模式,最关键的是确定T1的自动重装数RELOAD,步骤如下:

  1. 计算RELOAD(SMOD=0时)
    a) 12T模式的计算公式:RELOAD=256-(int) (Fosc/Baud0/32/12+0.5)
    b) 1T模式的计算公式:RELOAD=256-(int) (Fosc/Baud0/32+0.5)
    式中: (int) (X+0.5)表示对X进行四舍五入
    Fosc晶振频率
    Baud0标准波特率
  2. 计算用RELOAD产生的波特率
    a) 12T Baud = Fosc/(256-RELOAD)/32/12
    b) 1T Baud = Fosc/(256-RELOAD)/32
  3. 计算误差
    error=(Baud-Baud0)/Baud0*100%
  4. 如果绝对误差>4.5% 要更换波特率频率或更换晶振频率,再重复1-4

上面的步骤来自于STC的官方手册。上面提到的12T模式是大多数51单片机的工作模式,STC的后续单片机支持1T模式,速度会快12倍。

串口的使用

下图展示了一些常用重装值(RELOAD)配置
RELOAD
对于常用的11.0592Mhz晶体下,9600Baud配置的代码封装成C文件和H文件,方便调用

uart.h文件

#ifndef __UART_H
#define __UART_H

#include <reg52.h>

void Uart_Init(void);
void Uart_SendData(unsigned char dat);
void Uart_SendString(unsigned char *s);

#endif

uart.c文件

#include "uart.h"

void Uart_Init(void)
{
	SCON  = 0x50;		        // SCON: 模式 1, 8位UART, 接收使能  
	TMOD |= 0x20;               // TMOD: Timer1,模式2, 8位自动重装
	TH1   = 0xFD;               // TH1:  重装值 波特率:9600 晶振:11.0592MHz  
	TR1   = 1;                  // TR1:  Timer1打开                         
	EA    = 1;                  //打开总中断
	//ES    = 1;                  //打开串口中断
}

void Uart_Isr() interrupt 4 using 1
{
    if (RI)
    {
        RI = 0;             //清除接收标志位
        
    }
    if (TI)
    {
        TI = 0;             //清除发送标志位
			
    }
}

void Uart_SendData(unsigned char dat)
{
	SBUF = dat;
	while (!TI);
	TI=0;
}

void Uart_SendString(unsigned char *s)
{
	while (*s)
		Uart_SendData(*s++); 
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值