nRF24L01无线介绍

引脚功能

CE:RX或TX模式选择
CSN:SPI片选信号
SCK:SPI时钟
MOSI:SPI数据输入
MISO:SPI数据输出
IRQ:可屏蔽中断脚

时序
51测试程序
实测可用!

#define TX_ADR_WIDTH    5
#define RX_ADR_WIDTH    5
#define TX_PLOAD_WIDTH  32
#define RX_PLOAD_WIDTH  32

#define MAX_TX  	0x10	//达到最大发送次数中断
#define TX_OK   	0x20	//TX发送完成中断
#define RX_OK   	0x40	//接收到数据中断

const uchar TX_ADDRESS[TX_ADR_WIDTH]={0xEE,0xDD,0xCC,0xBB,0xAA};	//发送地址
const uchar RX_ADDRESS[RX_ADR_WIDTH]={0xAA,0xBB,0xCC,0xDD,0xEE};

sbit CE   = P2^7;
sbit CSN  = P2^6;
sbit MISO = P2^3;
sbit MOSI = P2^4;
sbit SCK  = P2^5;
sbit IRQ  = P2^2;

sbit LED=P1^0;

void delay_us(uchar num)
{
	uchar i; 
	for(i=0;i>num;i++)
 	_nop_();
}

void delay(uint t)
{
	uchar k;
	while(t--)
	for(k=0;k<200;k++);
}

uchar SPI_RW(uchar byte)
{
	uchar bit_ctr;
	for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
	{
		MOSI = (byte & 0x80); // output 'byte', MSB to MOSI
		byte = (byte << 1); // shift next bit into MSB..
		SCK = 1; // Set SCK high..
		byte |= MISO; // capture current MISO bit
		SCK = 0; // ..then set SCK low again
	}
	return(byte); // return read byte
}

uchar SPI_Write_Reg(uchar reg, uchar value)
{
	uchar status;
	CSN = 0; // CSN low, init SPI transaction
	status = SPI_RW(reg); // select register
	SPI_RW(value); // ..and write value to it..
	CSN = 1; // CSN high again
	return(status); // return nRF24L01 status byte
}

uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes)
{
	uchar status,byte_ctr;
	CSN = 0; // Set CSN low, init SPI tranaction
	status = SPI_RW(reg); // Select register to write to
	for(byte_ctr=0; byte_ctr<bytes; byte_ctr++) // then write all
		SPI_RW(*pBuf++);
	CSN = 1; // Set CSN high again
	return(status); // return nRF24L01 status byte
}

void RX_Mode_Init(void)
{
	CE=0;
	SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);
	SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH);
	SPI_Write_Reg(WRITE_REG + EN_AA, 0x01); // Enable Auto.Ack:Pipe0
	SPI_Write_Reg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0
	SPI_Write_Reg(WRITE_REG + RF_CH, 0);
	SPI_Write_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH);
	SPI_Write_Reg(WRITE_REG + RF_SETUP, 0x0f);
	SPI_Write_Reg(WRITE_REG + CONFIG, 0x0f); // Set PWR_UP bit, enable
	CE = 1; // Set CE pin high to enable RX device
}

uchar SPI_Read_Reg(uchar reg)
{
	uchar reg_val;
	CSN = 0; // CSN low, initialize SPI communication
	SPI_RW(reg); // Select register to read from..
	reg_val = SPI_RW(0); // ..then read registervalue
	CSN = 1; // CSN high, terminate SPI communication
	return(reg_val); // return register value
}

uchar NRF24L01_TxPacket(uchar *txbuf)
{
	uchar state;
   
	CE=0;
	SPI_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH); //写数据到TX_BUF
 	CE=1;
	while(IRQ==1); //等待发送完成
	LED = ~LED;
	state=SPI_Read_Reg(STATUS);  
	SPI_Write_Reg(WRITE_REG+STATUS,state); //清除中断标志TX_DS或MAX_RT
	if(state&MAX_TX) //达到最多重发中断
	{
		SPI_Write_Reg(FLUSH_TX,0xff); //清除TX FIFO寄存器
		return MAX_TX; 
	}
	if(state&TX_OK) //发送完成
	{
		return TX_OK;
	}
	return 0xff; //发送失败
}

void Send_Buf(uchar *buf)
{
	CE=0;
	SPI_Write_Reg(WRITE_REG+CONFIG,0x0e);
	CE=1;
	delay_us(15);
	NRF24L01_TxPacket(buf);
	CE=0;
	SPI_Write_Reg(WRITE_REG+CONFIG, 0x0f);
	CE=1;	
}

int main()
{
	uchar buf[TX_PLOAD_WIDTH];
	
	RX_Mode_Init();
	
	buf[0]=2; //无线串口模块需要第一位标识长度(忽略)
	buf[1]=0xaa;
	buf[2]=0x55;
	
	while(1)
	{
		Send_Buf(buf);
		
		delay(1000);
	}
}

模块不能自发自收

TX_ADDR和RX_ADDR_P0地址可以相同。但是TX_ADDR是目标板地址,RX_ADDR_P0是本模块地址。只有收发地址配置正确才能收发成功

最主要是RX_Mode_Init中寄存器的配置:
RF_CH,射频通道频率。收发必须一致(F0= 2400 + RF_CH [MHz])
RF_SETUP,射频寄存器。数据传输速率、发射功率、低噪声放大增益,收发必须一致
CRCO,校验方式。收发必须一致

posted @ 2017-08-07 22:24  thomas_blog  阅读(168)  评论(0编辑  收藏  举报