51单片机之串口通讯

什么是串口

        串行接口(Serial Interface)简称串口,也称串行通讯接口(通常指COM接口),是采用串行通信方式的扩展接口。串口通讯时数据是一位一位地顺序传送, 因此其优点是通信线路简单,只要一对传输线就可以实现双向通信,从而大大降低了成本,特别适用于远距离通信,通讯距离可以从几米到几千米,缺点是传送速度较慢。

与串口有关的寄存器

        51单片机与串口有关的有8个寄存器,我们需要用到的寄存器有SCON、SBUF、PCON。 

SBUF寄存器

 

        51单片机的说明书介绍了很多,也可能看不懂,我们只需要学会怎么用就好了。 

char data_msg = 'a';

SBUF = data_msg;

        用起来非常简单,定义一个字符变量,把字符传给SBUF就行了。这个寄存器不需要去配置,直接使用就好了。 

SCON寄存器 

 

 

        SCON寄存器有8个位,它的作用是用来配置波特率的模式、是否接收使能和串口中断之类的。我们暂时不关心串口中断和接收使能,主要是配置波特率模式,主要看SM0和SM1两个位。我们选择方式一 ,也就是0100 0000,转换16进制就是0x40。

SCON = 0x40;

 

PCON寄存器

 

 

        PCON寄存器比较简单,我们只需要关心SMOD和SMOD0这两个位就好了。但是这个资料有个错误的地方,SMOD置0时, 资料说的是波特率工作模式加倍,但事实上SMOD置0并没有加倍。

        我们选择波特率不加倍,也就是SMOD置0,因为51单片机的寄存器默认8位都为0,再加上也不需要使用SMOD0寄存器,所以我们可以不配置PCON寄存器。

什么是波特率

        在信息传输通道中,携带数据信息的信号单元叫码元,单位时间内通过信道传输的码元数称为码元传输速率,简称波特率,其单位是波特(Baud,symbol/s),波特率是传输通道频宽的指标。“波特”(Baud)本身已是速率,所以不需要写成 Baud Rate(Rate是赘字)。虽然单位“波特”本身就已经是代表每秒的调制数,以“波特每秒”为单位是一种常见的错误,但是在一般中文口语化的沟通上还是常以“波特率”来描述“波特”(Baud)。 

波特率的计算

定时器的配置

        如图可知,波特率我们需要用定时器1来计算,这时我们就需要配置TMOD寄存器。

        TMOD寄存器的配置,我们选择8位自动重载载定定时器这个模式,也就是把M1和M0配置为10。也就是0010 0000,转换为16进制是0x20。

TMOD &= 0x0F;    //高4为清零,低4位不变
TMOD |= 0x20;    //设定位8位重装模式

 

波特率计算

 

        我们选择的是工作方式一,然后以12T的模式来计算。SYSclk指的是晶振的频率,我这块51单片机晶振的频率是11.0592MHz。

        假设,我们想要的波特率位9600,那么可以推导出一个公式。

        9600 = (2^SMOD / 32) * 11059200 / 12 / (256 - TH1)

        在这个式子当中,SMOD是已知的,因为我们在PCON并没有配置它,所以SMOD为0。接下来只要求出TH1的值,在加上TH1的值和TL1的值是一样的,所以我们就可以配置波特率了。公式推导为:

        9600 = (1 / 32) * 921600 / (256 - TH1)

        9600 = 28800 / (256 - TH1)

        TH1的值为253,转换为16进制是0xFD。所以,定时器1的TH1 = 0xFD,TL1 = 0xFD。

void UartInit(void)		//9600bps@11.0592MHz
{
	
	SCON = 0x40; //配置串口工作方式1,REN不使能
	TMOD &= 0x0F;
	TMOD |= 0x20;//定时器1工作方式为8位自动重载
	
	TH1 = 0xFD;
	TL1 = 0xFD;//9600波特率初值
	
	TR1 = 1;	//开始计时
	
}

        当然,如果想要配置115200的波特率也可以自己推导。

总代码

#include "reg52.h"

void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	i = 43;
	j = 6;
	k = 203;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void UartInit(void)		//9600bps@11.0592MHz
{
	
	SCON = 0x40; //配置串口工作方式1,REN不使能
	TMOD &= 0x0F;
	TMOD |= 0x20;//定时器1工作方式为8位自动重载
	
	TH1 = 0xFD;
	TL1 = 0xFD;//9600波特率初值
	
	TR1 = 1;	//开始计时
	
}

void main()
{
	char data_msg = 'a';
	UartInit();
	while(1)
	{
		Delay1000ms();
		SBUF = data_msg;
	}
}

 

        

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

六花不会哭T﹏T

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值