24e1_repeater.c

来自「NRF24E1的信号中继程序,可使得传输距离更远,可用与做工业数据传输.」· C语言 代码 · 共 616 行 · 第 1/2 页

C
616
字号
//函数名:SendC()
//输入:发送的数据
//输出:无
//功能描述:串口初始化
/*****************************************************************************************/
void SendCh(char c)
{
	TI = 0;
	SBUF = c;
	while(!TI);
	TI = 0;
}

/*****************************************************************************************
//函数名:Nrf24E1Init()
//输入:无
//输出:无
//功能描述:Nrf24E1Init初始化,这里我们配置成32位地址。
/*****************************************************************************************/
void Nrf24E1Init()
{
	int8u i;
	SPICLK = 0;                                 // Max SPI clock
	SPI_CTRL = 0x02;                            // Connect internal SPI controller to Radio
	CE = 0;
	CS = 1;                                     // RF SPI CS = 1
	Delay100us(0);
	SpiReadWrite(0x00);                         // We are not using the DuoCeiver functionallity
	for(i=1;i<15;i++)
        {
		SpiReadWrite(RFConfig[i]);
        }
	CS = 0;

	Delay100us(30);  
}


/*****************************************************************************************
//函数名:Nrf24E1Init()
//输入:无
//输出:无
//功能描述:Nrf24E1Init初始化,这里我们配置成32位地址。
/*****************************************************************************************/
void Nrf24E1Init2()
{
	int8u i;
	SPICLK = 0;                                 // Max SPI clock
	SPI_CTRL = 0x02;                            // Connect internal SPI controller to Radio
	CE = 0;
	CS = 1;                                     // RF SPI CS = 1
	Delay100us(0);
	SpiReadWrite(0x00);                         // We are not using the DuoCeiver functionallity
	for(i=1;i<15;i++)
        {
		SpiReadWrite(RFConfig2[i]);
        }
	CS = 0;

	Delay100us(30);  
}

/*****************************************************************************************
//函数名:int8u WaitAck(void)
//输入:无
//输出:返回应答信号
//功能描述:等待应答,并返回应答信号
/*****************************************************************************************/
int8u WaitAck(void)
{
    int8u ack;
    SetRxMode();
    CE = 1;
    ResetTimer(0);
    while(DR1 == 0)
    {
        if (ReadTimer(0) > 10)                    // 3ms time-out/10MS
        {
            CE = 0;
            return 0;
        }
    }
    ack = SpiReadWrite(0);
    while(DR1)
    {
        SpiReadWrite(0);
    }
    CE = 0;
    return ack;
}

/*****************************************************************************************
//函数名:TransmitPacket(int8u *pBuf)
//输入:发送的数据
//输出:无
//功能描述:发送发送缓冲区的数据
/*****************************************************************************************/
/*****************************************************************************************
//函数名:TransmitPacket(int8u *pBuf)
//输入:发送的数据
//输出:无
//功能描述:发送发送缓冲区的数据
/*****************************************************************************************/
TransmitPacket(int8u *pBuf,int8u crc)
{
	int8u i;

	SetTxMode();
	CE = 1;
	Delay100us(1);

	for (i=0;i<ADDR_COUNT;i++)
	{
		SpiReadWrite(rfAddress2[i]);
	}
	SpiReadWrite(crc);
	for (i=0;i<4;i++)
	{
		SpiReadWrite(pBuf[i]);
	}
	CE = 0;
	Delay100us(6);                              // Wait until finished transmitting (200us + 256us)//delay(5)
}



/*****************************************************************************************
//函数名:void SendAck(unsigned char msgid)
//输入:发送的数据
//输出:无
//功能描述:发送发送缓冲区的数据
/*****************************************************************************************/
void SendAck(unsigned char msgid)
{
    
    int8u i;

    SetTxMode();
    CE = 1;
    Delay100us(2);

    for (i=0;i<4;i++)
    {
        SpiReadWrite(rfAddress[i]);
    }
    SpiReadWrite(msgid);                        
    CE = 0;
    Delay100us(1);                               
                                                
}
/*****************************************************************************************
//函数名:int8u ReceivePacket(int8u *pBuf)
//输入:接收数据缓冲区
//输出:成功返回1,否则返回0
//功能描述:接收数据存在缓冲区内
/*****************************************************************************************/
int8u ReceivePacket(int8u *pBuf)
{
	int8u i,cmd;

	SetRxMode();
	CE = 1;    
	ResetTimer(1);
	while(DR1 == 0)
	{
		if (ReadTimer(1) > 1000)
		{
			CE = 0;
			return 0;
		}
	}
	cmd = SpiReadWrite(0);
	i = 0;
	while(DR1)
	{
		pBuf[i] = SpiReadWrite(0);
		i++;
		if (i == 5)
		break;
	}
	while(DR1)
	{
		SpiReadWrite(0);
	}
	CE = 0;
	return cmd;
}

/******************************************************************************************
*******************************************************************************************
************************************中断服务程序*******************************************
*******************************************************************************************
******************************************************************************************/
void Timer0ISR (void) interrupt 1  using 1		//定时器0中断
{
	TF0 = 0;                                    	// Clear Timer0 interrupt
	TH0 = t0hrel;                               	// Reload Timer0 high byte
	TL0 = t0lrel;                               	// Reload Timer0 low byte
	timer[0]++;                                 	// Increment timer[0]
	timer[1]++;                                 	// Increment timer[1
}



/*
void UartISR (void) interrupt 4 using 2			//串口中断
{
	int8u temp;
	
	EA = 0;
	if(RI)
	{
		temp = SBUF;
		if(temp == '@')				//帧头
		{		
			Rx.Buf[0] = '@';
			Rx.Counter = 1;	
		}
		else if(temp == '*')			//帧尾
		{		
			Rx.Buf[Rx.Counter] = temp;
			Rx.Buf[Rx.Counter + 1] = '\0';
			Rx.NewData = 1;
		}
		else if(Rx.Counter < 39){
			Rx.Buf[Rx.Counter] = temp;
			Rx.Counter += 1;
		}
		RI = 0;
	}
	if(TI)
	{
		TI = 0;
	}
	EA = 1;
}

*/
/******************************************************************************************
*******************************************************************************************
******************************************主程序*******************************************
*******************************************************************************************
******************************************************************************************/
void main(void)
{	
	unsigned char temp,crc;
	unsigned char ack=0;                //ack为接收标记,若有则为1,退出循环
	unsigned char re_send_times,ack2;   //ack2为接受应答的值,若收到为0XAA

	SciInit();
	TimerInit();
	EA=1;  
	LEDR=0;
	LEDG=0;
	delay(5000);
	LEDR=1;
	LEDG=1;
	
	Nrf24E1Init();

	while(1)
	{
		temp = ReceivePacket(buf);
		crc=buf[0];
		if(temp != 0)
		{
			SendAck(0xaa);
			

			// 转发和重发机制
			ack=0;
			re_send_times=0;
			while(!ack)
			{
				Nrf24E1Init2();
				TransmitPacket(buf,crc);
				ack2=0;
				ack2=WaitAck();
				if(ack2!=0xaa)
				{
					LEDR=1;
					LEDG=0;
					delay(5000);
					LEDR=1;
					LEDG=1;
					ack=0;
					re_send_times++;
					if(re_send_times>=3) ack=1;
					delay(10000);	
				}
				else
				{
					LEDR=0;
					LEDG=0;
					delay(5000);
					LEDR=1;
					LEDG=1;
					ack=1;
				}
				
				
			}
			delay(5000);
			Nrf24E1Init();
			
		}
	}
}

⌨️ 快捷键说明

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