串口通信(4)一帧数据的接收

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

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

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

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

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

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

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

目录

一、项目设计

1.1功能设计

1.2硬件设计

1.2.1串口设计

1.2.2LED模块设计

1.3软件设计

1.3.1初始化

1.3.2接收中断

二、代码展示

2.1初始化

2.2接收中断

2.3主程序

2.4其他文件

三、结果展示

四、回顾文章及下文预告

五、模块整合

一、项目设计

1.1功能设计

虚拟串口com3发送数据,由单片机com1接收,CPU处理接收到的数据,让对应的LED亮。com3发数据0x01给单片机时,第一个LED亮;com3发数据0x02给单片机时,第二个LED亮;com3发数据0x03给单片机时,第三个LED亮;com3发数据0x04给单片机时,第四个LED亮。

1.2硬件设计

1.2.1串口设计

由于是com1与com3相互传输数据,所以com1的发送端TXD接com2的发送端TXD,com1的接收端RXD接com2的接收端RXD即可。

1.2.2LED模块设计

LED是共阳极接法,所以公共端接电源,LED要导通,右端(IO口)要是低电平。

1.3软件设计

1.3.1初始化

串口工作方式为方式1(8位异步通信),定时器采用定时器T1的工作方式2(8位自动重载),波特率为9600bit/s,晶振频率为11.0592Mhz。接收一帧数据的初始化,采用中断法。

串口通信中断法文章回顾:串口通信(二)-查询法与中断法-CSDN博客

1.3.2接收中断

单片机com1接收到数据时,RI自动置1,从而触发接收中断中断时别忘记将RI清0,以便单片机下次能够正确接收。因为接收完数据后要处理LED,所以要定义标志位recv_flag,用于判断接收是否完成。

二、代码展示

2.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开始计时
}

2.2接收中断

void ES_timer() interrupt 4
{
	if(RI) //接收中断
	{
		RI=0;//RI清0
		recv_date=SBUF;//接收数据
		recv_flag=1;//标志位,=1时说明接收完成
	}
}

2.3主程序

/*****************************************************************************
功 能:使用串口通信,采用中断法实现一帧数据的接收,并完成对应灯泡点亮的简单通讯协议
时 间:2023/10/28
*****************************************************************************/
#include <reg51.h>
#include "delay.h"
#include "uart.h"

void main()
{
	UartInit();
	while(1)
	{
		if(recv_flag)
		{
			switch(recv_date)
		  {
			  case 0x1:
					P1=0xfe;break;
				case 0x2:
					P1=0xfd;break;
				case 0x3:
					P1=0xfb;break;
				case 0x4:
					P1=0xf7;break;
		  }
		}
	}
}

2.4其他文件

#ifndef __UART_H__
#define __UART_H__

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

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

三、结果展示

下图标注如何使用串口助手com3发送数据给单片机的步骤(共5步)。

com3发送0x01:

com3发送0x02:

com3发送0x03:

com3发送0x04:

四、回顾文章及下文预告

回顾:

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

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

下一文讲述如何接收一串数据。

五、模块整合

目前,串口通信已经写了三篇,里面涉及到的函数要整合到一个.c文件和.h文件中

串口模块uart.c文件

#include "uart.h"

unsigned char recv_date;
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;
}

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

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

void ES_timer() interrupt 4
{
	if(RI) //接收中断
	{
		RI=0;
		recv_date=SBUF;
		recv_flag=1;
	}
}

串口模块uart.h文件:

#ifndef __UART_H__
#define __UART_H__

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

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

延时模块delay.c

#include "delay.h"
/******************************************************************************************
函数名:delay
功能:延时函数
参数:unsigned char xms
返回值:无
******************************************************************************************/
void delay(unsigned char xms)
{
	unsigned char i,j;
	for(i=xms;i>0;i--)
	  for(j=124;j>0;j--);
}

延时模块delay.h

#ifndef __DELAY_H__
#define __DELAY_H__

void delay(unsigned char xms);//延时函数声明

#endif

亲爱的读者敬请期待,下一文更精彩!!!

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

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

  • 8
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是基于51单片机的串口通信发送和接收数帧数据的代码: 发送数据的代码: ```c #include <reg51.h> #define BAUD_RATE 9600 void UART_Init() { TMOD |= 0x20; // Timer1 work on mode 2 TH1 = 256 - (11059200/12/32/BAUD_RATE); // Set the baud rate TR1 = 1; // Start timer1 SCON = 0x50; // Mode 1, 8-bit data, enable receive } void UART_SendByte(unsigned char dat) { SBUF = dat; while(!TI); TI = 0; } void UART_SendData(unsigned char *buf, int len) { int i; for(i=0; i<len; i++) UART_SendByte(buf[i]); } ``` 接收数据的代码: ```c #include <reg51.h> #define BAUD_RATE 9600 unsigned char RX_BUF[32]; unsigned char RX_CNT = 0; bit RX_FLAG = 0; void UART_Init() { TMOD |= 0x20; // Timer1 work on mode 2 TH1 = 256 - (11059200/12/32/BAUD_RATE); // Set the baud rate TR1 = 1; // Start timer1 SCON = 0x50; // Mode 1, 8-bit data, enable receive ES = 1; // Enable serial interrupt EA = 1; // Enable global interrupt } void UART_RxInt() interrupt 4 { if(RI) // Receive interrupt flag { RI = 0; RX_BUF[RX_CNT++] = SBUF; if(RX_CNT >= 32) RX_CNT = 0; RX_FLAG = 1; } } void UART_RecvData(unsigned char *buf, int len) { int i; while(!RX_FLAG); // Wait for data to be received for(i=0; i<len; i++) buf[i] = RX_BUF[i]; RX_CNT = 0; RX_FLAG = 0; } ``` 在主程序中,需要先初始化串口,然后可以使用UART_SendData和UART_RecvData函数来发送和接收数据。例如,发送一个长度为5的数据帧,可以这样写: ```c unsigned char data[] = {0x01, 0x02, 0x03, 0x04, 0x05}; UART_Init(); UART_SendData(data, 5); ``` 接收一个长度为10的数据帧,可以这样写: ```c unsigned char buf[10]; UART_Init(); UART_RecvData(buf, 10); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值