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

📄 com.c

📁 两颗51单片机通过串口通信的代码,独有的仲裁机制使得任一颗单片机都能成为主机.
💻 C
字号:
#include"com.h"
#include"main.h"
#include"lcd.h"


pdata unsigned char ucComRecBuf[24];
pdata unsigned char ucComSendBuf[24];
static unsigned char McuMasterOrSlaver=VMcuMaster;
static unsigned char ComMasterOrSlaver;


unsigned char ComSendStr_Return(unsigned char *SendBuf);
void ComStatus(void);
void ComMemoryRed(void);
void ComUSB(void);
void ComGetKey(void);
void ComTime(void);
void ComCharStatus(void);

code unsigned char FlagBitValue[16]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,
									 0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
//指向主机要求从机执行的函数的指针
code void (* ComDataProcess[])(void)=
{
	ComStatus,
	ComMemoryRed,
	ComUSB,
	ComGetKey,
	ComTime,
	ComCharStatus
};
void ComStatus(void)
{
	//设置主程序中的标志位。
	if((ucComRecBuf[2]&0x10)==0x10)
		MainFlag[ucComRecBuf[2]&0X07] = MainFlag[ucComRecBuf[2]&0X07] | 
										FlagBitValue[ucComRecBuf[2]>>5];
	else
		MainFlag[ucComRecBuf[2]&0X07] = MainFlag[ucComRecBuf[2]&0X07] &
									 FlagBitValue[(ucComRecBuf[2]>>5)+8];
	/////////////////////////////////////////////////////////////////////
	if((ucComRecBuf[2]==ComBoxNotPrivate)||(ucComRecBuf[2]==ComBoxHasPrivate))
		PreAndBackCom=PBBoxPrivate;
	if((ucComRecBuf[2]==ComBoxUsrCipherOk)||(ucComRecBuf[2]==ComBoxUsrCipherErr))
		PreAndBackCom=PBEntBoxUsrCipher;
	if((ucComRecBuf[2]==ComVerifyPswOk)||(ucComRecBuf[2]==ComVerifyPswErr))
		PreAndBackCom=PBVerifyPswResult;
	
}

void ComMemoryRed(void)
{
		ComSendStr_Return(GenaBuf2);
}

void ComUSB(void)
{

}
void ComGetKey(void)
{
	ucComRecBuf[23]=1;
	if(ucComRecBuf[2]==ComSendNewPsw)
		PreAndBackCom=PBEnterNewPsw;
}

void ComTime(void)
{

}
void ComCharStatus(void)
{

}


void ComInitial(void)
{
	PCON=PCON | 0X80;	SCON=0X90;	ES=1;EA=1;
	TMOD&=0XF0;TMOD|=0X01;TF0=0;ET0=1;TH0=VTh030ms;TL0=VTl030ms;TR0=1;
	ComMasterOrSlaver=VComNull;
	Time10ms=0;
}

//功能:从机给主机返回数据时使用此函数此函数进行发送
//参数:数据帧缓冲区。
unsigned char ComSendStr_Return(unsigned char *SendBuf)
{
	unsigned char tempSBUF;
	unsigned char i;
	unsigned char CheckByte=0;


//Sending command.....................................
	//	while(!RI);RI=0;

	for(i=0;i<3;i++)
	{
		if(i!=0)
		{
			SBUF=SendBuf[i-1];
			while(!TI);TI=0;
			CheckByte^=SendBuf[i-1];
		}
		Time10ms=0;
		while(Time10ms<150)
		{
			if(RI)
			{
				tempSBUF=SBUF;	RI=0;
				break;
			}
		}
		if(Time10ms>149)
			goto COMERROR;
		else
		{
			if(tempSBUF!=VComDataAck)
			{
				goto COMERROR;	
			}
		}
	}
	for(i=2;i<SendBuf[1]+3;i++)
	{
		if(i<SendBuf[1]+2)
			SBUF=SendBuf[i];
		else
			SBUF=CheckByte;
		while(!TI);TI=0;
		CheckByte^=SendBuf[i];
		Time10ms=0;
		while(Time10ms<150)
		{
			if(RI)
			{
				tempSBUF=SBUF;	RI=0;
				break;
			}
		}
		if(Time10ms>149)
			goto COMERROR;
		else
		{
			if(tempSBUF!=VComDataAck)
			{
				goto COMERROR;	
			}
		}
	}
	return 0;

COMERROR:
		return 83;
}

////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
unsigned char ComSendStr(void) reentrant
{
	unsigned char tempSBUF;
	unsigned char i;
	unsigned char CheckByte=0;

	ES=0;
//arbitrating............................................	
//发送仲裁码VComArbitrateReq,如果对方发回VComArbitrateAck,表示本机被仲裁为主机。
//如果对方发来的是VComArbitrateAck,表示双机同时想成为主机。此时优先级高(McuMasterOrSlaver==VMcuMaster)
//的单片机将成为主机,优先级低(McuMasterOrSlaver==VMcuSlaver)的单片机将成为从机,
	if(ComMasterOrSlaver==VComNull)
	{	
		SBUF=VComArbitrateReq;
		while(!TI);TI=0;
		Time10ms=0;
		while(Time10ms<150)
		{
			if(RI)
			{
				tempSBUF=SBUF;
				RI=0;
				break;
			}
		}
		if(Time10ms>149)
		{	ES=1;return ComRe_ArbitrateError;}/////////////////////////
		else
		{
			if(tempSBUF==VComArbitrateAck)
			{
				ComMasterOrSlaver=VComMaster;	
			}
			else if(tempSBUF==VComArbitrateReq)
			{
				SBUF=VComArbitrateAck;
				while(!TI);TI=0;
				Time10ms=0;
				while(Time10ms<150)
				{
					if(RI)
					{
						tempSBUF=SBUF;
						RI=0;
						break;
					}
				}
				if(Time10ms>149)
				{	ES=1;	return ComRe_ArbitrateError;}////////////////////
				else if(tempSBUF==VComArbitrateAck)
				{
					if(McuMasterOrSlaver==VMcuMaster)
						ComMasterOrSlaver=VComMaster;
					else
					{
						ComMasterOrSlaver=VComSlaver;
						//TI=0;RI=0;
						ES=1;
						return ComRe_IsSlaver;
					}
				}
			}
		}
	}
	else
	{
		ES=1;
		return ComRe_CanNotArbitrate;
	}

//Sending command.....................................

	if(ComMasterOrSlaver==VComMaster)
	{

		for(i=0;i<2;i++)
		{
			SBUF=ucComSendBuf[i];
			while(!TI);TI=0;
			CheckByte^=ucComSendBuf[i];
			Time10ms=0;
			while(Time10ms<150)
			{
				if(RI)
				{
					tempSBUF=SBUF;	RI=0;
					break;
				}
			}
			if(Time10ms>149)
			{	return 0x55;goto COMERROR;}/////////////////////
			else
			{
				if(tempSBUF!=VComDataAck)
				{	return 0x55;goto COMERROR;}/////////////////////
			}
		}

		for(i=2;i<ucComSendBuf[1]+3;i++)
		{
			if(i<ucComSendBuf[1]+2)
				SBUF=ucComSendBuf[i];
			else
				SBUF=CheckByte;
			while(!TI);TI=0;
			CheckByte^=ucComSendBuf[i];
			Time10ms=0;
			while(Time10ms<150)
			{
				if(RI)
				{
					tempSBUF=SBUF;	RI=0;
					break;
				}
			}
			if(Time10ms>149)
				goto COMERROR;
			else
			{
				if(tempSBUF!=VComDataAck)
				{
					goto COMERROR;	
				}
			}
		}

	
//Receiving data come from slaver......................................
		CheckByte=0;
		if((ucComSendBuf[0]&0xc0)==0x80)
		{
			SBUF=VComDataAck;
			while(!TI);TI=0;

			for(i=0;i<2;i++)
			{
				Time10ms=0;
				while(Time10ms<150)
				{
					if(RI)
					{
						ucComRecBuf[i]=SBUF;	RI=0;
						break;
					}
				}
				if(Time10ms>149)
					goto COMERROR;
				CheckByte^=ucComRecBuf[i];
				
				SBUF=VComDataAck;
				while(!TI);TI=0;
			}

			for(i=2;i<ucComRecBuf[1]+3;i++)
			{
				Time10ms=0;
				while(Time10ms<150)
				{
					if(RI)
					{
						ucComRecBuf[i]=SBUF;	RI=0;
						break;
					}
				}
				if(Time10ms>149)
					goto COMERROR;
				CheckByte^=ucComRecBuf[i];
				
				if(i<ucComRecBuf[1]+2)
					SBUF=VComDataAck;
				else
					if(CheckByte==0)
						SBUF=VComDataAck;
					else
						SBUF=VComDataNAck;
				while(!TI);TI=0;
			}
		}
	}
//COMOK:
		ComMasterOrSlaver=VComNull;
		TI=0;RI=0;ES=1;
		return ComRe_OK;

COMERROR:
		ComMasterOrSlaver=VComNull;
		TI=0;RI=0;ES=1;
		return ComRe_CommunicateError;

}






/*
中断函数调用此丛机接收函数
*/
unsigned char ComIntFunc(void) 
{

	unsigned char i;
	unsigned char CheckByte=0;
	void (*DataProcess)();

//Arbitrating ...............................................
	ES=0;
	if(TI)
	{
		TI=0;	return 1;
	}
	if(ComMasterOrSlaver==VComNull)
	{
		if(RI)
		{
			RI=0;
			if(SBUF==VComArbitrateReq)
			{
				SBUF=VComArbitrateAck;
				while(!TI);TI=0;
			}
		}
	}
	else if(ComMasterOrSlaver==VComMaster)
		return 84;
	
//Receiving data..................................................
	for(i=0;i<2;i++)
	{
		Time10ms=0;
		while(Time10ms<150)
		{
			if(RI)
			{
				ucComRecBuf[i]=SBUF;
				RI=0;
				CheckByte^=ucComRecBuf[i];
				break;
			}
		}
		if(Time10ms>149)
			goto COMINTERROR;
		SBUF=VComDataAck;
		while(!TI);TI=0;
	}

	for(i=2;i<ucComRecBuf[1]+3;i++)
	{
		Time10ms=0;
		while(Time10ms<150)
		{
			if(RI)
			{
				ucComRecBuf[i]=SBUF;
				RI=0;	break;
			}
		}
		if(Time10ms>149)
			goto COMINTERROR;
		CheckByte^=ucComRecBuf[i];
		if(i<(ucComRecBuf[1]+2))
			SBUF=VComDataAck;
		else
			if(CheckByte==0)
				SBUF=VComDataAck;
			else
				SBUF=VComDataNAck;
		while(!TI);TI=0;
	}
//根据应用码索引跳转到相应函数地址。
   	DataProcess=ComDataProcess[(ucComRecBuf[0]&0x3f)];
	(*DataProcess)();
//结束此次通信
//COMINTOK:
		ComMasterOrSlaver=VComNull;
		TI=0;RI=0;ES=1;
		return 0;
COMINTERROR:
		ComMasterOrSlaver=VComNull;
		TI=0;RI=0;ES=1;
		return 83;
}	







⌨️ 快捷键说明

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