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

📄 485mon.c

📁 51单片机C语言应用程序设计实例精讲.rar
💻 C
字号:
/****************************************/
/* Copyright (c) 2005, 通信工程学院     */
/* All rights reserved.                 */
/****************************************/

#include "485Mon.h"

void main(void)
{
	uchar type;

	/* 初始化 */
	init();
	
	while (1) 
	{
		if (Recv_Data(&type)==0)			// 接收帧错误或者地址不符合,丢弃
			continue;
		switch (type)
		{
			case ACTIVE:				// 主机询问从机是否在位
				Send_Data(READY,0,StatusBuf);	// 发送READY指令
				break;
			case GETDATA:				// 主机读设备请求
				Clr_StatusBuf();
				Get_Stat();				// 数据采集函数
				Send_Data(SENDDATA,strlen(StatusBuf),StatusBuf);
				break;
			default:
				break;					// 指令类型错误,丢弃当前帧
		}
	}
}

/* 初始化 */
void init(void)
{
	P1 = 0xff;
	DevNo = (P1&0x00111111);			// 读取本机设备号

	TMOD = 0x20;
	SCON = 0x50;
	TH1 = 0xfd;
	TL1 = 0xfd;
	TR1 = 1;
	PCON = 0x00;						// SMOD=0
	EA = 0;
						
}

/* 接收数据帧函数,实际上接收的是主机的指令 */
bit Recv_Data(uchar *type)
{
	uchar tmp,rCount,i;
	uchar r_buf[RECFRMMAXLEN];			// 保存接收到的帧
	uchar Flag_RecvOver;				// 一帧接收结束标志	
	uchar Flag_StartRec;				// 一帧开始接收标志
	uchar CheckSum;						// 校验和
	uchar DataLen;						// 数据字节长度变量
		
	/* 禁止发送,允许接收 */
	DE = 0;
	RE = 0;

	/* 接收一帧数据 */
	rCount = 0;
	Flag_StartRec = 0;
    Flag_RecvOver = 0;
	while (!Flag_RecvOver)
	{
		RI = 0;
		while (!RI);
		tmp = SBUF;
		RI=0;

		/* 判断是否收到字符'$',其数值为0x24 */          
		if ((!Flag_StartRec) && (tmp == 0x24))
		{
			Flag_StartRec = 1;	
		}

		if (Flag_StartRec) 
		{
			r_buf[rCount] = tmp;
			rCount ++;		
			
			/* 判断是否收到字符'*',其数值为0x2A,根据接收的指令设置相应标志位 */
			if (tmp == 0x2A)
				Flag_RecvOver = 1;
		}

		if (rCount == RECFRMMAXLEN)		// 帧超长错误,返回0
			return 0;
	}
	
	/* 计算校验和字节 */
	CheckSum = 0;
	DataLen = r_buf[3];
	for (i=0;i++;i<3+DataLen)
	{
		CheckSum = CheckSum + r_buf[i+1];
	}
	
	/* 判断帧是否错误 */
	if (rCount<6)						// 帧过短错误,返回0,最短的指令帧为6个字节						
		return 0;
	if (r_buf[1]!=DevNo)  				// 地址不符合,错误,返回0
		return 0;
	if (r_buf[rCount-2]!=CheckSum)		// 校验错误,返回0
    	return 0;

	*type = r_buf[2];					// 获取指令类型

	return 1;							// 成功,返回1
}

/* 发送数据帧函数 */
void Send_Data(uchar type,uchar len,uchar *buf)
{
	uchar i,tmp;
	uchar CheckSum = 0;
	
	/* 允许发送,禁止接收 */
	DE = 1;
	RE = 1;
	
	/* 发送帧起始字节 */
	tmp = 0x24;
	Send(tmp);
	
	Send(DevNo);						// 发送地址字节,也即设备号
	CheckSum = CheckSum + DevNo;
 
	Send(type);							// 发送类型字节
	CheckSum = CheckSum + type;

	Send(len);							// 发送数据长度字节
	CheckSum = CheckSum + len;
 
	/* 发送数据 */
	for (i=0;i<len;i++)			
	{
		Send(*buf);
		CheckSum = CheckSum + *buf;
		buf++;
	}
	
	Send(CheckSum);						// 发送校验和字节

	/* 发送帧结束字节 */
	tmp = 0x2A;
	Send(tmp);
}

/* 采集数据函数经过简化处理,取固定的10个字节数据 */
void Get_Stat(void)
{
	StatusBuf[0]=DATA0;
	StatusBuf[1]=DATA1;
	StatusBuf[2]=DATA2;
	StatusBuf[3]=DATA3;
	StatusBuf[4]=DATA4;
	StatusBuf[5]=DATA5;
	StatusBuf[6]=DATA6;
	StatusBuf[7]=DATA7;
	StatusBuf[8]=DATA8;
	StatusBuf[9]=DATA9;
}

/* 发送单字节数据 */
void Send(uchar m)
{
	TI = 0;
	SBUF = m;
    while(!TI);
	TI = 0;	
}

/* 清除设备状态信息缓冲区函数*/
void Clr_StatusBuf(void)
{
	uchar i;
	for (i=0;i<STATUSMAXLEN;i++)
		StatusBuf[i] = 0;	
}			

⌨️ 快捷键说明

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