51单片机串口使用

举报
yd_274589494 发表于 2023/07/27 17:41:42 2023/07/27
【摘要】 @TOC 前言今天将为大家讲解51单片机的串口原理及代码编写。 一、串口概念51单片机串口是一种通信接口,它可以将51单片机与外部设备连接起来,实现数据的双向传输。51单片机串口的原理是,51单片机的串口接口由两个管脚组成,一个是RXD,另一个是TXD,RXD用于接收数据,TXD用于发送数据。当51单片机接收到外部设备发送的数据时,它会将数据放入串口缓冲区,然后通过RXD管脚将数据发送到51...

@TOC


前言

今天将为大家讲解51单片机的串口原理及代码编写。

一、串口概念

51单片机串口是一种通信接口,它可以将51单片机与外部设备连接起来,实现数据的双向传输。51单片机串口的原理是,51单片机的串口接口由两个管脚组成,一个是RXD,另一个是TXD,RXD用于接收数据,TXD用于发送数据。当51单片机接收到外部设备发送的数据时,它会将数据放入串口缓冲区,然后通过RXD管脚将数据发送到51单片机的内部。当51单片机要发送数据时,它会将数据放入串口缓冲区,然后通过TXD管脚将数据发送到外部设备。
通过串口我们就能实现单片机和PC机的通信了。

二、中断中的RI、TI和SUBF

1.RI

RI是接收标志位,当51单片机接收到外部设备发送的数据时,RI会被置位。
当进行下一次接收时需要手动将RI清零。

2.TI

TI是发送标志位,当51单片机要发送数据时,TI会被置位。
当进行下一次发送时需要手动将TI清零。

3.SUBF

SBUF是串口缓冲区,它用于存放51单片机接收到的数据和要发送的数据。
SBUF一次只能发送和接收一个字节的数据。

三、串口波特率的计算

51单片机串口波特率的计算方法是:波特率=时钟频率/(16*(256-波特率寄存器值))。其中,时钟频率是51单片机的时钟频率,波特率寄存器值是51单片机的波特率寄存器的值。
一般我们是不会自己去计算串口的波特率的,我们使用STC-isp这个软件来帮助我们生成相应的代码。
STC-isp软件:
在这里插入图片描述
在STC-isp中可以帮助我们去生成对应的代码。
我们只需要注意波特率和系统频率等重要参数选择即可。
在这里插入图片描述
生成代码后将代码复制到自己的工程中就行了。

四、代码的编写

串口初始化代码

/*******************************************************************************
* 函 数 名       : uart_init
* 函数功能		 : 串口通信中断配置函数,通过设置TH和TL即可确定定时时间
* 输    入       : baud:波特率对应的TH、TL装载值
* 输    出    	 : 无
*******************************************************************************/
void uart_init(u8 baud)
{
	TMOD|=0X20;	//设置计数器工作方式2
	SCON=0X50;	//设置为工作方式1
	PCON=0X80;	//波特率加倍
	TH1=baud;	//计数器初始值设置
	TL1=baud;
	ES=1;		//打开接收中断
	EA=1;		//打开总中断
	TR1=1;		//打开计数器		
}

串口中断函数
每当串口接收或者发送一个字符串时都会进入串口中断。
RI和TI在上面我们已经说到过了,这里我就直接使用了。

这里定义一个busy发送标志位当在发送数据时busy=1代表串口进入了忙状态,当串口成功发送完一个字符时busy=0,进入空闲状态,这样可以保证我们每一个字符都被成功的发送出去。
定义一个buf用于接收PC机给单片机发送的数据。每当发生一次接收中断都会将接收到的字符串放入buf中。

bit busy = 0;//发送标志位
unsigned char buf[30];//接收缓冲区

void serial_handle() interrupt 4
{
	if(TI)
    {       
      TI = 0;
	  busy = 0;//进入空闲状态
    }
    else if(RI)
    {
		buf[i] = SBUF;
		i = (i + 1) % 30;
    }

}

发送一个字符和发送字符串函数
发送一个字符非常的简单,只需要将要发送的字符放入SBUF中即可。
发送一个字符串就是将字符串中的一个个的字符发送出去就可以了,这里用到了指针的操作不熟悉的小伙伴可以去复习一下C语言。

void SendData(unsigned char dat)
{
	while(busy);
	busy = 1;//进入忙状态	
	SBUF = dat;	
}

void SendString(char *s)
{
	while(*s)
	{
		SendData(*s++);
	}
}

发送测试

void main(void)
{
	/*主函数*/
	uart_init(0XFA);
	
	while(1)
	{
		SendString("Hello World\r\n");
		delayms(1000);
	}
	
}

效果:
每隔一秒就打印一次Hello World。
在这里插入图片描述
接收测试:

	if(strcmp(buf, "LED1 ON") == 0)
	{
		P2 = 0xfe;
		memset(buf, 0, sizeof(buf));
	}

在这里插入图片描述
在串口助手上发送LED1 ON让LED1打开,使用串口的数据后使用memset函数清空buf缓冲区,因为缓冲区的大小都是有限的,所以需要我们手动清空缓冲区。

总结

串口在debug中有非常重要的重要,希望大家都能够将他掌握。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。