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

📄 nrfdriver.c

📁 nRF2401的驱动程序
💻 C
字号:
#include "nRFConfig.h"
#include "HardWare_NRF.h"

INT8U nRF_Init(void);
void SwitchRX(void);
void SwitchTX(void);
INT8U WriteCFG(INT8U* buf, INT8U size);
INT8U ReadBuf_FromCH1(INT8U* buf, INT8U size, INT16U ticks);
INT8U ReadBuf_FromCH2(INT8U* buf, INT8U size, INT16U ticks);
INT8U SendBuf(INT8U* buf, INT8U size);

#if UCOS_NRF != 0
	void NRF_Dr_ISR(void);
#endif

static void WriteBuf(INT8U* buf, INT8U size);
static INT8U GetBuf_FromCH1(INT8U* buf, INT8U size);		//仅此文件内部使用
static INT8U GetBuf_FromCH2(INT8U* buf, INT8U size);		//仅此文件内部使用

#if UCOS_NRF !=0

	OS_EVENT *RecNrf_CH1Flag;
	OS_EVENT *RecNrf_CH2Flag;
	OS_EVENT *SendNrf_Flag;
	
	static INT8U nRF_Buf_CH1[BUFSIZE][DATA1_LEN_BYTE];
	static INT8U nRF_Buf_CH2[BUFSIZE][DATA2_LEN_BYTE];
	static INT8U front_CH1 = 0;
	static INT8U rear_CH1 = 0;
	static INT8U front_CH2 = 0;
	static INT8U rear_CH2 = 0;
	
	static INT8U HaveInit = 0; 
	
#endif


/*******************************************************************************************************************
** 函数名称: nRF_Init()				
**
** 功能描述: nRF无线模块初始化
**
** 输   入: 无
**	
** 输   出: 无
**
** 返 回 值: 1:   正确    , 0:	错误
********************************************************************************************************************/
INT8U nRF_Init(void)
{
	INT8U nRF_CFG[15] = 
	{
		DATA2_W,DATA1_W,							//通道1、2数据长度
		ADDR2_0,ADDR2_1,ADDR2_2,ADDR2_3,ADDR2_4,	//通道2地址
		ADDR1_0,ADDR1_1,ADDR1_2,ADDR1_3,ADDR1_4,	//通道1地址
		(INT8U)((ADDR_W<<2) + (CRC_L<<1) + CRC_EN),	//6位地址位数 1位CRC 8 OR 16位选择 1位CRC使能
		(INT8U)((RX2_EN<<7) + (CM<<6) + (RFDR_SB<<5) + (XO_F<<2) + RF_PWR),//通道2允许 通信模式、速率 晶振频率 发射功率设置
		(INT8U)((RF_CH<<1) + RXEN)					//7位频点设置 1位发射/接收选择 
	};

#if UCOS_NRF != 0
	if(HaveInit !=0)
	{
		return 0;				//判断初始化是否成功
	}
	else
	{
		HaveInit = 1;			//初始化成功
	}
#endif	
	
	HardWareIntialize();		//nRF无线模块硬件配置函数
	
	WriteCFG(nRF_CFG, 15);		//写配置字
	
	CS_CLR();
  	NOP();				//Td----min 50ns
  	CE_SET();			//Switch to Work Mode

#if UCOS_NRF != 0				/*	保证软件的可移植性	*/
	
	RecNrf_CH1Flag =	OSSemCreate(0);
	RecNrf_CH2Flag =	OSSemCreate(0);
	SendNrf_Flag =		OSSemCreate(1);

	INT_EN_DR1();
	INT_EN_DR2();
	
	SetISR_OWN(INT_NRF_DR_NO, INT_NRF_DR_PRIO, (INT32U)NRF_Dr_ISR);
	
#endif							/*	保证软件的可移植性	*/
	
	return 1;
}

/*******************************************************************************************************************
** 函数名称: WriteCFG()				
**
** 功能描述: 	写工作模式配置字
**
** 输   入: INT8U* buf ,INT8U size
**	
** 输   出: 无
**
** 返 回 值: 1:   正确    , 0:	错误
********************************************************************************************************************/
INT8U WriteCFG(INT8U* buf, INT8U size)
{
	if(size != 15)
	{
		return 0;
	}
#if UCOS_NRF != 0
	OS_ENTER_CRITICAL();
#endif

	CE_CLR();
	CS_CLR();
	CLK1_CLR();
	SI_CLR();
	
	PWRUP_SET();
	
	//DelayUS(1);			//Tpd2cfgm------max 3ms
	CS_SET();				//Switch to Cfg Mode
	DelayUS(5);				//Tcs2data---min 5us
	
	WriteBuf(buf, size);	//Write Configuration
	DelayUS(1);
	CS_CLR();				//Tell nRF to Update Configuration
	
#if UCOS_NRF != 0
	OS_EXIT_CRITICAL();
#endif
	
	return 1;	
}

/*******************************************************************************************************************
** 函数名称: SwitchRX()				
**
** 功能描述: 模式切换至接收状态		
**
** 输   入: 无
**	
** 输   出: 无
**
** 返 回 值: 无
********************************************************************************************************************/
void SwitchRX(void)
{
#if UCOS_NRF != 0
	OS_ENTER_CRITICAL();
#endif
	
	PWRUP_SET();
	CE_CLR();
	CS_CLR();
	CLK1_CLR();
	NOP();				//Td---min 50ns
  	CS_SET();
  	
  	DelayUS(5);			//Tcs2data---min 5us
  	
  	SI_SET();			//Set to Recv Mode
  	DelayUS(1);			//Ts----min 500ns
  	
  	CLK1_SET();
  	DelayUS(1);			//Thmin---min 500ns
  	CLK1_CLR();
  	
  	CS_CLR();
  	NOP();				//Td----min 50ns
  	CE_SET();			//Update Configuration
  	
  	DelayUS(1);			//Tsby2rx---max 202us

#if UCOS_NRF != 0
	OS_EXIT_CRITICAL();
#endif
}
/*******************************************************************************************************************
** 函数名称: SwitchTX()				
**
** 功能描述: 模式切换至发送状态		
**
** 输   入: 无
**	
** 输   出: 无
**
** 返 回 值: 无
********************************************************************************************************************/
void SwitchTX(void)
{
#if UCOS_NRF != 0
	OS_ENTER_CRITICAL();
#endif
	
	PWRUP_SET();
	CE_CLR();
	CS_CLR();
	CLK1_CLR();
	NOP();				//Td---min 50ns
  	CS_SET();
  	
  	DelayUS(5);			//Tcs2data---min 5us
  	
  	SI_CLR();			//Set to Send Mode
  	DelayUS(1);			//Ts----min 500ns
  	
  	CLK1_SET();
  	DelayUS(1);			//Thmin---min 500ns
  	CLK1_CLR();
  	
  	CS_CLR();
  	NOP();				//Td----min 50ns
  	CE_SET();			//Update Configuration
  	
  	DelayUS(1);			//Tsby2rx---max 202us

#if UCOS_NRF != 0
	OS_EXIT_CRITICAL();
#endif
}
/*******************************************************************************************************************
** 函数名称: WriteBuf()				
**
** 功能描述: 写数据到缓冲区	
**
** 输   入: INT8U* buf, INT8U size
**	
** 输   出: 无
**
** 返 回 值: 无
********************************************************************************************************************/
static void WriteBuf(INT8U* buf, INT8U size)
{
	INT8U i, j, dat;
	
	CLK1_CLR();
	for(i=0;i<size;i++)
	{
		dat = buf[i];
		for(j=0;j<8;j++)
		{
		    CLK1_CLR();
			if(dat & 0x80)
			{
				SI_SET();
			}
			else
			{
				SI_CLR();
			}
			
			DelayUS(1);         //Ts--min 500ns        
   			CLK1_SET();
   			DelayUS(1);			//Th--min 500ns
   			
   			dat = dat << 1;
		}
	}
}
/*******************************************************************************************************************
** 函数名称: SendBuf()				
**
** 功能描述: 从缓冲区发送数据	
**
** 输   入: INT8U* buf, INT8U size
**	
** 输   出: 无
**
** 返 回 值: 0
********************************************************************************************************************/
INT8U SendBuf(INT8U* buf, INT8U size)
{
	INT8U send_len;
#if UCOS_NRF != 0
	INT8U err;
	OSSemPend(SendNrf_Flag, OS_TICKS_PER_SEC, &err);
	if(err != OS_NO_ERR)
	{
		return 0;
	}
#endif
	
	if(size > (DATA1_LEN_BYTE + 4))
	{
		send_len = DATA1_LEN_BYTE + 4;
	}
	else
	{
		send_len = size;
	}

	CE_SET();
	DelayUS(5);					//Tce2data---min 5us
	WriteBuf(buf, send_len);
	CE_CLR();					//发送需要一段时间的延迟
	
#if  UCOS_NRF != 0				
	OSTimeDly(1);
	OSSemPost(SendNrf_Flag);
#else							
	#if RFDR_SB == 1			//1Mbps
		DelayUS(750);
	#else						//250Kbps
		DelayUS(1400);
	#endif
#endif

	return 0;
}
/*******************************************************************************************************************
** 函数名称: ReadBuf_FromCH1()				
**
** 功能描述: 从通道1 读取数据		
**
** 输   入: INT8U* buf, INT8U size, INT16U ticks 
**	
** 输   出: 无
**
** 返 回 值: 1:   正确    , 0: 	错误
********************************************************************************************************************/
INT8U ReadBuf_FromCH1(INT8U* buf, INT8U size, INT16U ticks)
{
#if UCOS_NRF != 0						/*	保证软件的可移植性	*/
	INT8U err;
	
	OSSemPend(RecNrf_CH1Flag, ticks, &err);
	if(err != OS_NO_ERR)
	{
		return 0;
	}
	
	OS_ENTER_CRITICAL();
	if(rear_CH1 != front_CH1)
	{
		front_CH1 = (front_CH1 + 1) % BUFSIZE;
		if(size >= DATA1_LEN_BYTE)
		{
			memcpy(buf, nRF_Buf_CH1[front_CH1], DATA1_LEN_BYTE); 
		}
		else
		{
			memcpy(buf, nRF_Buf_CH1[front_CH1], size);
		}
	} 
	OS_EXIT_CRITICAL();
	
	return 1;							/*	保证软件的可移植性	*/
#else
	ticks = ticks;
	if (GET_DR1_STAT() == 0) 
	{
		return 0;						//未使能通道一中断输出
	}
	
  	return GetBuf_FromCH1(buf, size);	//将数据写入缓冲区
#endif
	
}
/*******************************************************************************************************************
** 函数名称: ReadBuf_FromCH2()				
**
** 功能描述: 从通道2 读取数据		
**
** 输   入: INT8U* buf, INT8U size, INT16U ticks 
**	
** 输   出: 无
**
** 返 回 值: 1:   正确    , 0: 	错误
********************************************************************************************************************/
INT8U ReadBuf_FromCH2(INT8U* buf, INT8U size, INT16U ticks)
{
#if UCOS_NRF != 0						/*	保证软件的可移植性	*/
	INT8U err;
	
	OSSemPend(RecNrf_CH2Flag, ticks, &err);
	if(err != OS_NO_ERR)
	{
		return 0;
	}
	
	OS_ENTER_CRITICAL();
	if(rear_CH2 != front_CH2)
	{
		front_CH2 = (front_CH2 + 1) % BUFSIZE;
		if(size >= DATA2_LEN_BYTE)
		{
			memcpy(buf, nRF_Buf_CH2[front_CH2], DATA2_LEN_BYTE); 
		}
		else
		{
			memcpy(buf, nRF_Buf_CH2[front_CH2], size);
		}
		
	}
	else
	{
		return 0;
	}
	OS_EXIT_CRITICAL();
	
	return 1;							/*	保证软件的可移植性	*/
#else
 	ticks = ticks;
	if (GET_DR2_STAT()==0) 
	{
		return 0;						//未使能通道2中断输出
	}
	
  	return GetBuf_FromCH2(buf, size);	//将数据写入缓冲区
#endif
	
}
/*******************************************************************************************************************
** 函数名称: GetBuf_FromCH1()				
**
** 功能描述: 根据时序配置按位将数据写入通道1Buf		
**
** 输   入: INT8U* buf, INT8U size 
**	
** 输   出: 无
**
** 返 回 值: 1:   正确   , 0:	错误
********************************************************************************************************************/
static INT8U GetBuf_FromCH1(INT8U* buf, INT8U size) 		//仅此文件内部使用
{
	INT8U i, j;
 	INT8U dat;
 	
 	if (DATA1_LEN_BYTE > size)
 	{
 		return 0;
 	}
 	
	DelayUS(50);								//Tdr2clk---min 50us
	for(i=0;i<DATA1_LEN_BYTE;i++)
	{
  		dat = 0;
  		for(j=0;j<8;j++)
  		{
  			dat = dat << 1;
  			CLK1_SET();
  			DelayUS(1);			//Thmin---min 500ns
  			if(GET_SO_STAT() != 0)
  			{
  				dat += 1;
  	   		}
  	   		CLK1_CLR();
  	   		DelayUS(1);     //  Tclk2data  Max=50us    ADD
  		}
  		buf[i] = dat;
  	}
  	
  	return 1;
}
/*******************************************************************************************************************
** 函数名称: GetBuf_FromCH2()				
**
** 功能描述: 根据时序配置按位将数据写入通道2Buf		
**
** 输   入: INT8U* buf, INT8U size 
**	
** 输   出: 无
**
** 返 回 值: 1:   正确   , 0:	错误
********************************************************************************************************************/
static INT8U GetBuf_FromCH2(INT8U* buf, INT8U size) 		//仅此文件内部使用
{
	INT8U i, j;
 	INT8U dat;
 	
 	if (DATA2_LEN_BYTE > size)
 	{
 		return 0;
 	}
 	
	DelayUS(50);								//Tdr2clk---min 50us
	for(i=0;i<DATA2_LEN_BYTE;i++)
	{
  		dat = 0;
  		for(j=0;j<8;j++)
  		{
  			dat = dat << 1;
  			CLK2_SET();
  			DelayUS(1);			//Thmin---min 500ns
  			if(GET_DOUT2_STAT() != 0)
  			{
  				dat += 1;
  	   		}
  	   		CLK2_CLR();
  	   		DelayUS(1);     //  Tclk2data  Max=50us    ADD
  		}
  		buf[i] = dat;
  	}
  	
  	return 1;
}

/*******************************************************************************************************************
** 函数名称: NRF_Dr_ISR()				
**
** 功能描述: nRF无线模块驱动 中断服务函数	
**
** 输   入: 无
**	
** 输   出: 无
**
** 返 回 值: 无
********************************************************************************************************************/
#if UCOS_NRF != 0												

void NRF_Dr_ISR(void)											/*	保证软件的可移植性	*/					
{
	#if OS_CRITICAL_METHOD == 3                                /* Allocate storage for CPU status register */
    	OS_CPU_SR  cpu_sr;
	#endif    
	
	if(GET_INT_DR1_STAT() != 0)
	{
		INT_CLR_DR1();	
		OSIntEnter();
	
		if (((rear_CH1+1)%BUFSIZE) == front_CH1)		//如果队列已满,则丢弃最远的数据
		{
			front_CH1 = (front_CH1 + 1) % BUFSIZE;
		}
		else
		{
			OSSemPost(RecNrf_CH1Flag);
		}
		rear_CH1 = (rear_CH1 + 1) % BUFSIZE;
		GetBuf_FromCH1(nRF_Buf_CH1[rear_CH1], DATA1_LEN_BYTE);
	
		VIC_CLR();
		OSIntExit();
	}
	else if(GET_INT_DR2_STAT() != 0)
	{
		INT_CLR_DR2();
		OSIntEnter();
	
		if (((rear_CH2+1)%BUFSIZE) == front_CH2)		//如果队列已满,则丢弃最远的数据
		{
			front_CH2 = (front_CH2 + 1) % BUFSIZE;
		}
		else
		{
			OSSemPost(RecNrf_CH2Flag);
		}
		rear_CH2 = (rear_CH2 + 1) % BUFSIZE;
		GetBuf_FromCH2(nRF_Buf_CH2[rear_CH2], DATA2_LEN_BYTE);
		
		VIC_CLR();
		OSIntExit();
	}
}														/*	保证软件的可移植性	*/						

#endif				//#if UCOS_NRF != 0	

⌨️ 快捷键说明

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