串口通信(5)-一串固定长度数据的接收

本文详细描述了单片机通过串口通信功能的设计,包括功能设定、硬件配置、软件初始化、数据接收和发送过程。作者使用CSDN平台分享了如何使用定时器中断来处理非固定长度数据接收,适合初学者学习单片机串口通信技术。
摘要由CSDN通过智能技术生成

 本文为博主 日月同辉,与我共生,csdn原创首发。希望看完后能对你有所帮助,不足之处请指正!一起交流学习,共同进步!

> 发布人:@日月同辉,与我共生_单片机-CSDN博客

> 欢迎你为独创博主日月同辉,与我共生点赞❤❤❤+关注👍+收藏🌹+评论☺。

系列专栏: CSDN-单片机串口通信学习系列🎁

> 我的格言是:“尽最大努力,做最好的自己!💪

要转载,请提前告知!!!

版权声明:本文为CSDN博主「日月同辉,与我共生」的原创文章,CSDN独一份。

d5c7d9f7abb74cd9aaad50e81b0cb965.png

目录

一、功能设计

二、硬件设计

三、软件设计

3.1初始化

3.2接收一串数据

3.3发送数据

四、结果显示

五、知识回顾

一、功能设计

功能:单片机com1先发送please xie a date.,当虚拟串口com3发送8个数据,由单片机接收到后,单片机将这8个数据发送回虚拟串口com3。

二、硬件设计

硬件设计可以参考前面的文章:博主csdn文章-串口通信(2)

虚拟终端RXD接单片机com1的接收端RXD。

ee63ba4c063a41e58306db420e9b3840.png

三、软件设计

3.1初始化

初始化时,要设置寄存器SCON(工作方式、是否多机通信、数据位数),REN一般要接收(置1),初值就是定时初始值TH1/定时重载值TL1,工作方式为方式1(8位异步重载),波特率设置为9600bit/s,晶振频率为11.0592Mhz,因为串口通信是8位数据传输,所以定时器为定时器T1工作方式为方式2,还要打开总中断EA=1,串口中断开关ES=1。

void UartInit(void)		//9600bps@11.0592MHz
{
	PCON &= 0x7F;		//波特率不倍速
	SCON = 0x50;		//8位数据,可变波特率
	TMOD &= 0x0F;		//设置定时器模式
	TMOD |= 0x20;		//设置定时器模式
	TL1 = 0xFD;			//设置定时初始值
	TH1 = 0xFD;			//设置定时重载值
	ET1 = 0;			//禁止定时器中断
	ES=1;
	EA=1;
	TR1 = 1;			//定时器1开始计时
}

3.2接收一串数据

数组:k常数,定义数组int a[k],a[k]存储了k个元素,数据元素类型为int,a[0]=a0,a[k-1]=a k-1,最末尾有结束符‘\0’。当代码发送到字符等于‘\0’时,说明发送字符串已经完成

*是解引用符,&是地址符。p存储有a的地址,所以*p会根据a的地址找到a的值,即*p=a;

而数组本质上是一个指针常量,使用下标代表每个元素的值,可以用指针代替下标,由指针代表每个元素值。a[]为一个数组,int *p=a;语句*p=a,此时指针默认指向下标0,即*p的值为a[0],语句*p++;可以让指针由原来指向下标0变为指向下标1,即此时*p=a[1]。

当RI=1会触发接收中断,在中断服务函数中,接收数据,并将RI清0,当接收完8个数据后,将标志位recv_flag置1(说明接收完成)。

void ES_timer() interrupt 4 
{
	static unsigned char datecnt=0;
	if(RI) //接收中断
	{
		RI=0;
		recv_date[datecnt++]=SBUF;//将接收到的数据赋给变量---SBUF--接收串行数据寄存器
		if(recv_date==8)//固定8个字符
		{
			recv_flag=1;//中间变量置1
			datecnt=0;
		}
	}
}

3.3发送数据

当标志位recv_flag=1时,说明单片机接收完成,则单片机将数据重新发送给虚拟串口com3。

#include <reg51.h>
#include "delay.h"
#include "uart.h"

void main()
{
	UartInit();
	printf("please xie a date.\r\n");
	while(1)
	{
		if(recv_flag)
		{
			recv_flag=0;
			sendString(recv_date);//发送一串数据
		}
	}
}

四、结果显示

b4390719c19f438e8a109f1782118c3c.png

好多人不懂十六进制和文本模式的,今天博主教你们。

当com3在发送缓冲区以HXT模式(十六进制模式)发送十六进制数0-9,接收缓冲区相当于单片机com1,模式为HXT模式时,接收到的数据也是十六进制。虚拟终端若选择HXT模式,接收到的数据也是十六进制。

758962b5cf9245c0b5dfa08e3efdce9c.png

ad57be21b6064ef69ddd563106074294.png

当com3在发送缓冲区以文本模式发送数字0-9,接收缓冲区相当于单片机com1,模式为文本模式时,接收到的数据也是数字0-9。虚拟终端若不选择HXT模式,接收到的数据也是数字0-9。值得注意的是,文本模式是com3可以发送字符/字符串的,接收到的结果是正确的。

9a0281902ade49c9b8a50365ca9d2057.png

c5759a1ef7f5474b80151fe9e51c089a.png

发送字符:

04a06ec94c804acfb5ff7c5fe9cf72cc.png

3989db0be882476385c9c0e9ba203849.png

发生字符串:

6ce9e58bef7243f4837cab1ead4ab31a.png

6b02918f12214202893bc975952c6d3c.png

五、知识回顾

回顾串口通信文章:

串口通信(一)-通信理论及相关参数-CSDN博客

串口通信(二)-查询法与中断法-CSDN博客

串口通信(3)printf串口输出重定向的实现及一帧一串数据的发送

串口通信(4)一帧数据的接收-CSDN博客

将上述文章代码整合一下:

uart.c

#include "uart.h"

#define MAXdate 20  //字符最大长度

unsigned char recv_date[MAXdate];
unsigned char recv_flag=0;

void UartInit(void)		//9600bps@11.0592MHz
{
	PCON &= 0x7F;		//波特率不倍速
	SCON = 0x50;		//8位数据,可变波特率
	TMOD &= 0x0F;		//设置定时器模式
	TMOD |= 0x20;		//设置定时器模式
	TL1 = 0xFD;			//设置定时初始值
	TH1 = 0xFD;			//设置定时重载值
	ET1 = 0;			//禁止定时器中断
	ES=1;
	EA=1;
	TR1 = 1;			//定时器1开始计时
}


void sendByte(unsigned char dat) //发送一帧数据功能函数
{
	SBUF=dat;//发送数据
	while(!TI);//等待发送成功
	TI=0;//发送标志位置0
}

void sendString(unsigned char *dat) //发送字符串函数 unsigned char *dat=123
{
	while(*dat != '\0')
	{
		sendByte(*dat++);
	}
}

char putchar(char c)
{
	sendByte(c);
	return c;
}

void ES_timer() interrupt 4 
{
	static unsigned char datecnt=0;
	if(RI) //接收中断
	{
		RI=0;
		recv_date[datecnt++]=SBUF;//将接收到的数据赋给变量---SBUF--接收串行数据寄存器
		if(recv_date==8)//固定8个字符
		{
			recv_flag=1;//中间变量置1
			datecnt=0;
		}
	}
}

uart.h

MAXdate是数据长度最大值,本文设计用的数据长度为8,也可改成其他长度,但不能超过20。修改数据长度,只需在接收中断模块的if语句修改条件即可。

#ifndef __UART_H__
#define __UART_H__

#include <reg51.h>
#include <stdio.h>

#define MAXdate 20 

extern unsigned char recv_date[];
extern unsigned char recv_flag;

void UartInit();
void sendByte(unsigned char dat);
void sendString(unsigned char *dat);
char putchar(char c);

#endif

下一文将着重如何用定时器中断完成非固定长度的数据接收,亲爱的读者请多多支持博主大大,下一文更精彩!!!

一日不读书,胸臆无佳想。我叫不白吃,喜欢我的,可以支持我,博主名叫@日月同辉,与我共生

@日月同辉,与我共生_单片机基础,单片机串口通信-CSDN博客@日月同辉,与我共生擅长单片机基础,单片机串口通信,等方面的知识,@日月同辉,与我共生关注stm32,c语言,51单片机,proteus,单片机领域.https://blog.csdn.net/LIN___IT?spm=1000.2115.3001.5343

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值