51单片机串行发收字符串

//1.串行调试助手不会自动发送结束符'' !!!
//2.判断字符串是否接收完毕需要结合 RI是否为1 与 是否接收超时
//3.进入串行中断函数之后虽然设置ES=0 RI=0 防止后续的字节再次发送过来程序还没有出串行中断子函数 RI又被置为1了
//4.只能用定时器1来设定波特率 不能用定时器0 波特率是根据定时器1的溢出率来设定的 一般定时模式使用模式2,8位,自动重装 !!!!!
//5.方式2 就是8 位计数器,tl计数,溢出时,机器将th的值装到tl,这就是自动重装。因为,tl1满了后, 机器自动重装th1的数到tl1,所以初值一样。

#include<reg52.h>
//#define N 30		//一次性接收字符串的个数  接收数组大小	 注意下方Build Output数据data不要超过128
#define time 100	//在接收函数中通过判断是否接收超时来判断字符串是否接收完毕

unsigned char* Receive(unsigned int* );
void Send(unsigned char* tr);

void main()
{	
	
	TMOD=0x20;			//模式2	自动重装入初值的8位定时器
	SCON=0X50;
	TH1=0XFD;  			//FF波特率28800	 FD波特率9600
	EA=1;
	TR1=1;
	ES=1;

	P0=0XF0;

	while(1)	;
}  

void ver() interrupt 4
{	
	unsigned int rec_i=0;	//接收字符个数
	unsigned char* rec;	//接收字符串首地址
	ES=0;

	rec=Receive(&rec_i); 
	
	P0=~P0;

	//Send("123456789");
	Send(rec);
	 
	RI=0;
	ES=1;
} 



void Send(unsigned char *tr)
{
	while(*tr)
	{
		SBUF=*tr;
		while(!TI)	;
		TI=0;
		tr++;
	}
	TI=0;	
}

unsigned char* Receive(unsigned int* rec_i)
{
	int rec_fin_flag=0;
	unsigned count=0;		//超时机制 用于短暂计数用作延时
	//unsigned char rec_str[N];
	unsigned char* rec_str;

	while(rec_fin_flag!=1)  
	{
		rec_str[(*rec_i)]=SBUF;
		RI=0;
		(*rec_i)++;
		count=0;
		while(rec_fin_flag==0)
		{
			if(RI==1)	break;
			count++;
			if(count==time) rec_fin_flag=1;
		}
	} 	
	RI=0;
	return rec_str; 	
}
原文地址:https://www.cnblogs.com/maskerk/p/7348833.html