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

📄 main.c

📁 无线模块nrf2401的收和发C51程序
💻 C
字号:
#include <string.h>
#include <reg52.h>
#include <intrins.h>

#define 	INT8U		unsigned char
#define 	INT16U		unsigned int

#define		FOSC		11059200
#define		BAUD		9600
#define		TIMER1		0XFD	//256-(110592/(12*32*96))
#define		TIMER0H		(65535-3*FOSC/12/1000)/256
#define		TIMER0L		(65535-3*FOSC/12/1000)%256			//定时3MSVR
//----------------------------------------------------------------------------------------------------------
//内部寄存器定义
//----------------------------------------------------------------------------------------------------------
//sfr	P4		=	0xc0;
//sfr 	ADC_CONTR 	= 	0xC5;
//sfr 	AUXR 		= 	0x8E;
//sfr 	ADC_DATA 	= 	0xC6;
//sfr 	P1_ADC_EN 	= 	0x97;
//定义I/O口
sbit	POW_UP	=	P1^0;
sbit	CE	=	P1^1;
//sbit	DR2	=	P3^3;
//sbit	SCK2	=	P3^2;
sbit	MOSI	=	P1^2;  //DATA1
sbit	MISO	=	P1^3;  //DR1
sbit	SCK	=	P1^5;  //clk1
//sbit	DOUT2	=	P1^5;
sbit	CS	=	P1^4;
sbit	DR1	=	P1^2;
sbit	LED1	=	P3^4;
sbit	LED2	=	P3^5;


/********************* I/O define end*****************************************************/


#define   	FRESELE		0x28		//频道选择
#define 	DATANUM		4		//有效数据位数

#define time0h (65535-3000)/256
#define time0l (65535-3000)%256			//定时3MS




INT8U CofigBuf[15]=
		{
		0x00,				//接收频道二有效数据长度

		40,				//接收频道一有效数据长度

		0x00,0x00,0x00,0x00,0x00,	//接收频道二地址

		0x00,0xcd,0xef,0x12,0xaa,	//接收频道一地址

		0x83,				//32位地址,16位CRC,使能CRC
						//bit7~2:ADDR_W,最大40位

						//bit1:CRC_L
						//Logic 0: 8 bit CRC
						//Logic 1: 16 bit CRC


						//BIT0:CRC_EN
						//Logic 0: On-chip CRC generation/checking disabled
						//Logic 1: On-chip CRC generation/checking enabled


		0x4f,				//ShockBurst模式,250 kbps,16M晶振,0dBm最大功率

						//Bit 15:RX2_EN
						//Logic 0: One channel receive
						//Logic 1: Two channels receive

						//Bit 14:
						//Communication Mode:
						//Logic 0: nRF2401 operates in direct mode.
						//Logic 1: nRF2401 operates in ShockBurst. mode

						//Bit 13:
						//RF Data Rate:
						//Logic 0: 250 kbps
						//Logic 1: 1 Mbps

						//Bit 12-10:Selects the nRF2401 crystal frequency to be used:
						//	D12 	D11 	D10 	Crystal Frequency [MHz]
						//	0   	0 	0 		4
						//	0 	0 	1 		8
						//	0 	1 	0 		12
						//	0 	1 	1 		16
						//	1 	0 	0 		20

						//Bit 9-8:RF_PWR: Sets nRF2401 RF output power in transmit mode:
						//	D9 	D8 	P [dBm]
						//	0 	0 	-20
						//	0	1 	-10
						//	1 	0 	-5
						//	1 	1 	0



		0x50			//2400+4*1=2404MHZ=2.404G,发送模式

						//Bit 7 – 1:RF_CH#: Sets the frequency channel the nRF2401 operates on.
						//Channelrf = 2400MHZ + RF_CH# * 1.0MHZ

						//Bit 0:Set active mode:
						//Logic 0: transmit mode
						//Logic 1: receive mode
		};


INT8U AddrCofig[4]={0xcd, 0xef, 0x12, 0xaa};				//地址
INT8U TxBuf[8]={0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00};	//发送绶冲区
INT8U RxBuf[8]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};	//接收绶冲区
INT16U timer[2];								//超时计数器



/*****************************************************************************************
//函数名:void Delay100us(INT8U s)
//输入:时间
//输出:无
//功能描述:廷时
/*****************************************************************************************/
void Delay100us(INT8U n)
{
	INT8U i;
	while(n--)
	{
		for(i=0; i<35; i++);
	}
}
/*****************************************************************************************
//函数名:delay(unsigned int s)
//输入:时间
//输出:无
//功能描述:普通廷时
/*****************************************************************************************/
delay(unsigned int s)
{
	unsigned int i;
	for(i=0; i<s; i++);
	for(i=0; i<s; i++);
}
/*****************************************************************************************
//函数名:CpuInit()
//输入:无
//输出:无
//功能描述:SPI初始化程序
/*****************************************************************************************/
CpuInit(void)
{
	POW_UP = 1;
	Delay100us(40);
	CE = 0;
	CS = 0;
//	SCK = 0;
}

/*****************************************************************************************
//函数名:void TimerInit(void)
//输入:无
//输出:无
//功能描述:定时器0初始化程序
/*****************************************************************************************/
void TimerInit(void)
{
	TH0 = TIMER0H;
	TL0 = TIMER0L;
	ET0 = 1;			//定时器0中断允许
	TF0 = 0;
	TR0 = 1;			//启动定时器0
	EA = 1;				//开全局中断
}


/*****************************************************************************************
//函数名:ResetTimer(INT8U n)
//输入:要复位的计时器
//输出:无
//功能描述:复位计时器
/*****************************************************************************************/
void ResetTimer(INT8U n)
{
	ET0 = 0;                                    // Disable Timer0 interrupt
	timer[n & 0x01] = 0;                        // Clear timer[n]
	ET0 = 1;                                    // Enable Timer0 interrupt
}


/*****************************************************************************************
//函数名:INT16U ReadTimer(INT8U n)
//输入:要读的计时器
//输出:读出值
//功能描述:读计时器
/*****************************************************************************************/
INT16U ReadTimer(INT8U n)
{
	INT16U tmp;
	ET0 = 0;                                    // Disable Timer0 interrupt
	tmp = timer[n];                             // Clear timer[n]
	ET0 = 1;                                    // Enable Timer0 interrupt
	return tmp;
}

/*****************************************************************************************
//函数名:UartInit()
//输入:无
//输出:无
//功能描述:串口初始化程序
/*****************************************************************************************/
void UartInit(void)
{
	SCON = 0x50;		//串口方式1,允许接收
	TMOD = 0x21;		//定时器1工作方式2,定时器0工作方式1
	TH1 = TIMER1;
	TL1 = TIMER1;
	TR1 = 1;		//启动定时器1
}


/*****************************************************************************************
//函数名:SendCh(ch)
//输入:无
//输出:无
//功能描述:串口发送一个字符
/*****************************************************************************************/
void SendCh(INT8U ch)
{
	SBUF = ch;
	while(!TI);
	TI = 0;
}


/*****************************************************************************************
//函数名:void SpiWriteByte(INT8U dat)
//输入:发送的数据
//输出:无
//功能描述:SPI发送一个字节
/*****************************************************************************************/
void SpiWriteByte(INT8U dat)
{
	INT8U i;

	SCK = 0;
	_nop_();
	_nop_();
	for(i=0; i<8; i++)
	{
		if((dat & 0x80) == 0x80)
		{
			MOSI = 1;
			MISO = 1;
		}
		else
		{
			MOSI = 0;
			MISO = 0;
		}
		dat <<= 1;
		SCK = 1;
		_nop_();
		_nop_();
		SCK = 0;
		_nop_();
		_nop_();
	}
}


/*****************************************************************************************
//函数名:INT8U SpiReadByte(void)
//输入:无
//输出:读出的数据
//功能描述:SPI读出一个字节
/*****************************************************************************************/
INT8U SpiReadByte(void)
{
	INT8U i,temp;
	temp = 0;

	MISO = 1;
	MOSI = 1;

	SCK = 0;
	_nop_();
	_nop_();
	for(i=0; i<8; i++)
	{
		temp <<= 1;
		SCK = 1;
		_nop_();
		_nop_();
		if(MISO)temp++;
		SCK = 0;
		_nop_();
		_nop_();
	}
	return temp;
}

/*****************************************************************************************
//函数名:SetTxMode()
//输入:无
//输出:无
//功能描述:转为发送模式
/*****************************************************************************************/
void SetTxMode(void)
{
    	unsigned char ch;
    	CS = 1;
    	Delay100us(0);
    	ch = FRESELE<<1;
    	SpiWriteByte(ch);
    	CS = 0;
    	Delay100us(2);
}

/*****************************************************************************************
//函数名:SetRxMode()
//输入:无
//输出:无
//功能描述:转为接收模式
/*****************************************************************************************/
void SetRxMode(void)
{
    	unsigned char ch;
    	CS = 1;
    	Delay100us(0);
    	ch = FRESELE<<1;
    	SpiWriteByte(ch | 0x01);
    	CS = 0;
    	Delay100us(2);				//200us
}



/*****************************************************************************************
//函数名:Nrf2401Init()
//输入:地址,发送数据位数
//输出:无
//功能描述:Nrf2401Init初始化,这里我们配置成32位地址。
/*****************************************************************************************/
void Nrf2401Init(void)
{
	INT8U i;
	CE = 0;
	CS = 1;

	Delay100us(0);
	for(i=0; i<15; i++)
	{
		SpiWriteByte(CofigBuf[i]);
	}

	CS = 0;

	Delay100us(30);

}


/*****************************************************************************************
//函数名:TranData()
//输入:无
//输出:无
//功能描述:发送发送缓冲区的数据。
/*****************************************************************************************/
void TranData(void)

{
	INT8U i;

	SetTxMode();

	CE = 1;

	Delay100us(1);

	for(i=0; i<4; i++)
	{
		SpiWriteByte(AddrCofig[i]);	//发送地址
	}
	for(i=0; i<5; i++)
	{
		SpiWriteByte(TxBuf[i]);		//发送五位
	}


	CE = 0;

	Delay100us(13);
}



/*****************************************************************************************
//函数名:void ReceiveBytes(void)
//输入:无
//输出:无
//功能描述:接收数据存在接收缓冲区内
/*****************************************************************************************/
INT8U ReceivePacket(void)
{
	INT8U i;
	SetRxMode();
	CE = 1;
	ResetTimer(1);
	while(DR1 == 0)
	{
		if(ReadTimer(1) > 1000)
		{
			CE = 0;
			return 0;
		}
	}
	i = 0;
	while(DR1)
	{
		RxBuf[i] = SpiReadByte();
		i++;
		if (i == 5)
		break;
	}
	while(DR1)
	{
		SpiReadByte();
	}
	CE = 0;
	return 1;
}

/******************************************************************************************
*******************************************************************************************
************************************中断服务程序*******************************************
*******************************************************************************************
******************************************************************************************/
void Timer0ISR(void) interrupt 1
{
	EA = 0;
	TH0+=TIMER0H;
	TL0+=TIMER0L;
	timer[0]++;
	timer[1]++;
	EA = 1;
}





/******************************************************************************************
*******************************************************************************************
******************************************主程序*******************************************
*******************************************************************************************
******************************************************************************************/
main()
{
	INT8U temp, i;
	CpuInit();
	TimerInit();
	UartInit();
	LED1=0;
	LED2=0;
	delay(20000);
	LED1=1;
	LED2=1;
	Nrf2401Init();
	delay(500);

	while(1)
	{
		temp = ReceivePacket();
	   	if(temp == 1)
		{
			LED1=0;
			delay(5000);
			LED1=1;
			for(i=0; i<5; i++)
			{
				SendCh(RxBuf[i]);
			}
		}
	}
}


⌨️ 快捷键说明

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