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

📄 rf24e1.c

📁 基于无线单片机24e1的组网程序。在无线传感器之类的应用中的成功案例。
💻 C
📖 第 1 页 / 共 2 页
字号:
	return 100;
}
//================================================================
//函数功能:检验接收
//filename:VerifyRxd()
//input:none
//output:数据报头位置(eb90eb90+数据报)
//================================================================
unsigned char VerifyRxd(void)
{
	//signed char locat;

	Loc=FindHead();
	if( Loc > 10 )
	{//没有找到同步头

		return 0xff;
		
	}
	if( (inBuf[Loc]+Loc) > inCnt )
	{//长度不够

		return 0xff;

	}
	if( inBuf[Loc+1] != 0x11 )
	{//类型不对

		return 0xff;
	}
	if( inBuf[Loc+2] != 0 )
	{//组号不对

		return 0xff;
	}
	if( inBuf[Loc+3] != 0 )
	{//地址不对

		return 0xff;
	}

	if(!RxdCheckSum())
	{//校验不对
		return 0xff;
	}
//SBUF=locat;

	return Loc;
}

//================================================================
//函数功能:启动发送
//filename:StartSend()
//input:none
//output:none
//================================================================
void StartSend(void)
{	
	outBuf[0] = 0xeb;
	outBuf[1] = 0x90;
	outBuf[2] = 0xeb;
	outBuf[3] = 0x90;
	outBuf[5] = 0x11;
	outBuf[6] = 0x00;
	outBuf[7] = 0x00;
	outBuf[9] = 0x00;//????????????????状态
	outCnt = outBuf[4]+3;
	cTxdDptr = 1;//注:串口发送中断从outBuf[1]开始发送,直到outCnt为零
	TxdCheckSum( );
	SBUF = 0xeb;

}

//================================================================
//函数功能:检查串口接收缓冲区,根据命令段含义作出响应动作
//filename:CheckRxd()
//input:none
//output:none
//================================================================
void CheckRxd(void)
{
	unsigned char  locat,jj;
	unsigned int  kk;
//	unsigned char cpu_sr;
 	if( bRxd )
	{   	
		if( cRxdTime >3)				//串口有接收20ms 后可以认为全部数据业已到达
		{
						 				//20ms后查看接收缓冲区的信息是什么冬冬。

		//	ES=0;						//正在处理接收缓冲区,禁止中断,以免这时有以外的数据进来
			bRxd = 0;	
			locat = VerifyRxd();		//校验数据
			if(locat < 10 )
			{//	Led_Tx=0;				//找到同步头
				switch( inBuf[locat+4] )//这个位置是命令段
				{
				case 0:					//查询数据(呼叫电池组电压、电流)
					outBuf[4] = 12;		//长度段
					outBuf[8] = 0x80;	//命令段(或0x80)
					outBuf[10]=LOCAL_ADC.adcByte[1];	//电池组电压值
					outBuf[11]=LOCAL_ADC.adcByte[0];
					outBuf[12]=LOCAL_ADC.adcByte[3];	//电池组电流值
					outBuf[13]=LOCAL_ADC.adcByte[2];
					StartSend();
					break;
				case 1: //查询单节电池电压	
						//串口发送缓冲区:255,所以每次仅可以发送60个节点的信息,60x4=240
					if(Group1_Num)
					{
					kk=4*Group1_Num;
					outBuf[8] = 0x81;
					/*locat=0;
					do
						{
						outBuf[11+locat]=Node_V[NdBfoutV++];
						}while((++locat<240)&&(NdBfoutV<(4*Group1_Num)));
					if(NdBfoutV>=(4*Group1_Num))
						NdBfoutV=0;*/
					/*if(jj<=240)
						{
						for(locat=0;locat<jj;locat++)
							outBuf[11+locat]=Node_V[NdBfoutV];
						}
					else
						{
						if(NdBfoutV<240)
							{
							for(locat=0;locat<240;locat++)
								{
								outBuf[11+locat]=Node_V[NdBfoutV++];
								}
							}
						 else
						 	{
							jj=jj-NdBfoutV;
							for(locat=0;locat<jj;locat++)
								outBuf[11+locat]=Node_V[NdBfoutV++];

							NdBfoutV=0;
							}
						}*/
					
					for(locat=0;locat<241;locat++)
						{
						if(NdBfoutV>=kk)
							{
							NdBfoutV=0;
							break;
							}
						outBuf[11+locat]=Node_V[NdBfoutV++];
						
					 	}
					outBuf[4]=9+locat;
					outBuf[10]=locat;
					StartSend();
				
					}
					break;
				case 2://查询单节电池温度
					if(Group1_Num)
					{
					kk=Group1_Num<<2;
					outBuf[8] = 0x82;
					/*locat=0;
					do
						{
						outBuf[11+locat]=Node_T[NdBfoutT++];
						}while((++locat<240)&&(NdBfoutT<(4*Group1_Num)));*/
					for(locat=0;locat<240;locat++)
						{
						if(NdBfoutT>=(4*Group1_Num))
							{
							NdBfoutT=0;
							break;
							}
						outBuf[11+locat]=Node_T[NdBfoutT++]; 
						}
					outBuf[4]=9+locat;
					outBuf[10]=locat;
					StartSend();
					}
					break;
				case 3://节点地址注册,每次少于等于100个节点
						//inBuf[115]:4+8+121=133
					Group1_Num=inBuf[locat+6];
					for(jj=0;jj<Group1_Num;jj++)//节点数量
						{
						Group1_Table[jj]=inBuf[locat+7+jj];  
						}

					outBuf[4] = 0x08;
					outBuf[8] = 0x83;//注册完成回复
					StartSend();
					NodeResistered=1;
					break;
				case 4://启动巡检
					enrF = 1;
					outBuf[4] = 0x08;
					outBuf[8] = 0x84;
					StartSend();
					break;
				case 5://本机无线地址和节点地址高三字节的确定
					//PtAddr=(unsigned char xdata *)(0x0fe8);
					for(jj=0;jj<4;jj++)
						{
						rconf.buf[ADDR_INDEX+jj]=inBuf[10+jj];//本机地址
						tconf.buf[ADDR_INDEX+jj]=inBuf[14+jj];//节点地址
						}

					outBuf[4]=8;
					outBuf[8]=0x85;
					
					rFaddrResistered=1;
					fRfInit();//每配置一次节点、本机无线地址都必须初始化无线子系统一次because....
					StartSend();
					break;
				default:
					break;
				}//switch( inBuf[locat+4] )
			}//if( locat < 10 )
			
			EA=0;
			cRxdTime = 0;
			inCnt = 0;//接收处理完毕,计数器清零
			EA=1;
		//	ES=1;
		}///if(cRxTime>2)
	}//if(bRxd)
	else
	{
		cRxdTime = 0;
	}
}
/*
void SendCh(unsigned char c)
{	
	EA=0;
	TI=0;
	SBUF = c;
	while(!TI);
	TI=0;
	EA=1;	
}*/
//================================================================
//函数功能:将收到的节点采样值按顺序存入节点采样值缓冲区
//filename:SaveNodeInfo()
//input:bit valid=1,收到有效的采样值,如实存入,否则该节点无响应,存入max value
//output:none
//================================================================
void SaveNodeInfo(bit valid)
{			unsigned char jj;
			if(!valid)//节点无响应。
			{
				for(jj=0;jj<4;jj++)
				{
					adcResult_list[jj][0]=0xff;
					adcResult_list[jj][1]=0xff;
				}
			}
				// 一个节点的2个通道的电压存入缓冲
			Node_V[NodeBufCnt]=adcResult_list[0][1];//低字节
			Node_V[NodeBufCnt+1]=adcResult_list[0][0];
			Node_V[NodeBufCnt+2]=adcResult_list[1][1];//高字节
			Node_V[NodeBufCnt+3]=adcResult_list[1][0];		
				//一个节点的2个通道的温度存入缓冲,并调整指针
			Node_T[NodeBufCnt++]=adcResult_list[2][1];
			Node_T[NodeBufCnt++]=adcResult_list[2][0];
			Node_T[NodeBufCnt++]=adcResult_list[3][1];
			Node_T[NodeBufCnt++]=adcResult_list[3][0];
			if(NodeBufCnt>=400)NodeBufCnt=0;	
			else 
				{
				if(NodeBufCnt>=4*Group1_Num)
				    NodeBufCnt=0;//100个以下节点的情况
				}
}


//================================================================
//main()>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//================================================================
main()
{	
	unsigned  char idata RxMsg=0;
	unsigned int idata adc_temp;
	unsigned int idata adctime;
	unsigned char idata i,b,jj;
//	unsigned int xdata t_50ms;
	SysInit();
	InitADC();
   	ptnode=0;				
	EA=1;

	while((!NodeResistered)||(!rFaddrResistered))//上电后等待m128注册节点和无线地址
		CheckRxd();
//	NodeResistered=0;
//	rFaddrResistered=0;
//	Led_Rx=0;

	while(1)
	{	
		  	//SetTxMode();
			//////////////////////////////设置发送模式//////////////
re_ask:   	CE = 0;
    		CS = 1;
    		Delay100us(0);
    		SpiReadWrite(tconf.buf[14]);
    		CS = 0;
			////////////////////////////////////////////////////////
			Led_Tx=0;
			Led_Rx=1;
			//TransmitCMD(Group1_Table[ptnode]);
			//////////////////////////////发送查询命令//////////////
			CE = 1;
    		Delay100us(0);
			tconf.buf[ADDR_INDEX+ADDR_COUNT-1]=Group1_Table[ptnode];
    		for(i=0;i<ADDR_COUNT;i++)
				{
    			SpiReadWrite(tconf.buf[ADDR_INDEX+i]);	//写目标地址
				}
    		SpiReadWrite('f');							//写数据(8字节)
			CE = 0;
    		Delay100us(3);                  	  		// Wait ~300us   
			/////////////////////////////////////////////////////////
			//Delayms(5);								//这个时间是必须的,因为可能没发完不要改变工作模式
			Delayms(3);								//250kbps,64bits需要0.256ms
		/*	Delay100us(200);
			Delay100us(200);
			Delay100us(200); */
			//SetRxMode();
			////////////////////////////////////设置接收模式///////
    		CE = 0;
    		CS = 1;																			   
    		Delay100us(0);
    		SpiReadWrite(rconf.buf[14]);
    		CS = 0;
			///////////////////////////////////////////////////////
			Led_Tx=1;
			CheckRxd(); 
			ReqTimeout=0;
			//Led_Tx=1;
			//RxPack();	
			///////////////////////////////////无线接收///////////////
    		CE = 1;
    		while(!DR1)
				{
				if(ReqTimeout>50)//50ms超时
					{
					ReqTimeout=0xff;
					goto asktimeout;//break;
					}					
				}
			jj=0;
			while(DR1)
				{
    			b = SpiReadWrite(0);
				adcResult_list[jj][0]=b;
				b=SpiReadWrite(0);
				adcResult_list[jj++][1]=b;
				ReqTimeout=0;
				}
 asktimeout:CE = 0;
			//////////////////////////////////////////////////////////
			if(ReqTimeout==0xff)		//超时出来的
				{
				if(++CallTime==2)		//重呼2次,坚决放弃和她的联系
					{	SaveNodeInfo(0);//该节点对应的缓冲位置存入0xff
						goto endQ;
					}
				goto re_ask;
				}
			Led_Rx=0;					//接收LED闪烁
			SaveNodeInfo(1);			//缓冲接收到的节点采样值
			Delay100us(100);
endQ:		if(++ptnode>=Group1_Num)
				ptnode=0;
			CallTime=0;
		//200ms搞一次电池组电压电流采样
		//----------------ADC采样处理,平滑均值滤波处理---------------------
		//----------------ADC_LIST[2][16]	
		//----------------ADC_SUM[2]
		//----------------adcResult_list[X]=ADC_SUM[X]/16
	/*if(++adctime>2000)
		{		adctime=0;*/
/*				ADC_SUM[0] -=ADC_LIST[0][ADC_Cnt];		//各个通道的累加和减去最老采样值,
				ADC_SUM[1] -=ADC_LIST[1][ADC_Cnt];
				InitADC();							    //不明白,否则转换结果保持是最后一个通道的结果
	    		ADC_LIST[0][ADC_Cnt]=ReadShowADC(1);	//读出第1个通道的采样值(电流)
				InitADC();
				ADC_LIST[1][ADC_Cnt]=ReadShowADC(2);	//读出第2个通道的采样值(电压)	

				ADC_SUM[0] +=ADC_LIST[0][ADC_Cnt];		//各个通道的累加和加上最新采样值,
				ADC_SUM[1] +=ADC_LIST[1][ADC_Cnt];
				*/
/**************************
				InitADC();
				adc_temp=ReadShowADC(1);
				ADC_SUM[0]+=adc_temp;
				adc_temp=ReadShowADC(2);
				ADC_SUM[1]+=adc_temp;
				ADC_Cnt++;
				if(ADC_Cnt>=128)
					{
					ADC_Cnt=0;
					LOCAL_ADC.adc_value.local_A=ADC_SUM[0]>>7;
					LOCAL_ADC.adc_value.local_V=ADC_SUM[1]>>7;
					ADC_SUM[0]=0;
					ADC_SUM[1]=0;
					}*/         //*****
				//LOCAL_ADC.adc_value.local_A=(ADC_SUM[0])>>4;			//通道1平均值(sum/16)
				//LOCAL_ADC.adc_value.local_V=(ADC_SUM[1])>>4;			//通道2平均值
/*				Led_Rx=~Led_Rx;
				SendCh(LocalADC[0]>>8);
				SendCh(LocalADC[0]);

				SendCh(LocalADC[1]>>8);
				SendCh(LocalADC[1]);
*/
				//if(++ADC_Cnt==16)ADC_Cnt=0;				//调整指针	
	/*	}*/	

	}

	
}


//================================================================
//函数功能:TIMER0中断服务程序(实现1秒定时)
//filename:
//input: none
//output:none
//================================================================
void Timer0_isr(void) interrupt 1 
{ //   static unsigned char idata OneSCnt;

    TR0 = 0; 
	TH0=0xcb;
	TL0=0xea;				//reload the counter
    if(bRxd)
		cRxdTime++;
	ReqTimeout++;			//无线查询超时计数器
	TR0=1;
}  

⌨️ 快捷键说明

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