⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pmpdatar.c

📁 本程序利用51单片机实现点对多点的数据传输
💻 C
字号:
/*****************************************/
/* Copyright (c) 2005, 通信工程学院      */
/* All rights reserved.                  */
/* 作    者:戴 佳						 */
/*****************************************/

#include "PMPDataR.h"

/* 延时t毫秒 */
void delay(uint t)
{
	uint i;
	while(t--)
	{
		/* 对于11.0592M时钟,约延时1ms */
		for (i=0;i<125;i++)
		{}
	}
} 

/* 发送数据函数 */
uchar recvdata(uchar *buf)
{
	uchar i,tmp;
	uchar len;					// 保存数据长度
	uchar ecc;					// 保存校验字节
	
	/* 接收数据长度字节 */
	RI = 0;
	while(!RI);
	if (RB8==1)					
		return 0xee;			// 若接收的为地址帧,则返回0xee
	len = SBUF;
	RI = 0;
	
	/* 使用len的值为校验字节ecc赋初值 */
	ecc = len;					

	/* 接收数据 */
	for (i=0;i<len;i++)
	{
		while(!RI);
		if (RB8==1)
			return 0xee;		// 若接收的为地址帧,则返回0xee
		*buf = SBUF;	
		ecc = ecc^(*buf);		// 进行字节校验
		RI = 0;	
		buf++;		
	}
	*buf = 0;					// 表示数据结束
	
	/* 接收校验字节 */
	while(!RI);
	if (RB8==1)					
		return 0xee;			// 若接收的为地址帧,则返回0xee
	tmp = SBUF;
	RI = 0;

	/* 进行数据校验 */
	ecc = tmp^ecc;
	if (ecc!=0)					// 如果校验错误
	{
		*(buf-len) = 0;			// 清空数据缓冲区
		
		/* 发送校验错误信号ERR */
		TI = 0;	
		TB8 = 0;
		SBUF = ERR;
		while(!TI);
		TI = 0;

		return 0xff;			// 返回0xff表示校验错误
	}

	/* 发送校验成功信号SUCC */
	TI = 0;
	TB8 = 0;
	SBUF = SUCC;
	while(!TI);
	TI = 0;

	return 0;					// 校验成功,返回0
}

/* 串口初始化函数 */
void init_serial()
{
	TMOD = 0x20;				// 定时器T1使用工作方式2
	TH1 = 250;
	TL1 = 250;
	TR1 = 1;					// 开始计时
	PCON = 0x80;				// SMOD = 1
	SCON = 0xd0;				// 工作方式,9位数据位,波特率9600kbit/s,允许接收 
}

/* 主程序 */
void main()
{ 
	uchar i = 0;
	uchar tmp = 0xff;

	addr = P1&0x0f;				// 获取本机地址

	P20 = 1;					// 发光管不亮
	
	init_serial();				// 串口初始化 

	EA = 0;						// 关闭所有中断
	
	/* 进入设备应答 */
	while(1)
	{
		SM2 = 1;				// 只接收地址帧

		/* 如果接收到的地址帧不是本机地址,则继续等待 */
		tmp = addr-1;
		while (tmp!=addr)
		{
			RI = 0;
			while(!RI)
			tmp = SBUF;
			RI = 0;
		}	

		/* 发送本机地址作为应答信号,准备接收数据 */
		TI = 0;				
		TB8 = 0;				// 主机不检测该位
		SBUF = addr;
		while(!TI);
		TI = 0;
		SM2 = 0;				// 允许接收数据

		/* 数据接收 */
		tmp = 0xff;
		while(tmp==0xff)		// 如果校验失败则重新接收数据
		{
			/* 校验失败返回0xff,检测到地址帧则返回0xee,接收成功返回0 */
			tmp = recvdata(buf);	
		}
		if (tmp==0x00)			// 校验正确,表示接收成功
		{
			/* 绿灯亮,持续500ms,表示接收数据成功 */
			P20 = 0;			
			delay(500);
			P20 = 1;	
		}	    
		// 如果接收数据时发现地址帧,则重新开始整个接收过程
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -