nrf24l01检测不到 CD载波检测

后使用快捷导航没有帐号?
查看: 1241|回复: 5
在线时间4 小时
TA的帖子TA的资源
一粒金砂(中级), 积分 6, 距离下一级还需 194 积分
一粒金砂(中级), 积分 6, 距离下一级还需 194 积分
有没有使用过NRF24L01+的大神啊?
小弟调试这个模块两周了就是搞不定啊。我用的是TMS320F28027,自带的SPI写的程序。
网上大部分是模拟SPI,我使用的自带的。
现在就是我给可以写值的寄存器写值是没问题的。例如我给CONFIG写0f读回来的也是0f。
问题是我现在发布出去,如果把EN_AA关闭后,STATUS的值可以从默认的14变到46,
但是接收端是没有反应的。
NRF24L01+有一个载波检测功能,
就是09号寄存器,我在接收端发现竟然连这个寄存器都无法检测到载波信号。
我真的是陷入绝望了。已经两周没睡好觉了。求求用过的大神指点一二。我的qq.
跪谢了~~~~
在线时间217 小时
芯币1356 枚
TA的帖子TA的资源
一粒金砂(中级), 积分 80, 距离下一级还需 120 积分
一粒金砂(中级), 积分 80, 距离下一级还需 120 积分
很好弄的,特别要注意寄存器的参数,只要基础的读写时序正确基本可以通信的,
实在想省事就向供应商要参考代码吧
在线时间4 小时
TA的帖子TA的资源
一粒金砂(中级), 积分 6, 距离下一级还需 194 积分
一粒金砂(中级), 积分 6, 距离下一级还需 194 积分
基本的寄存器的参数我都读了都写进去了,也对的。照着datasheet对了好几遍。。就是不行。。。真的快跪了。。。会不会是我买到了假货?淘宝买的2.5一个。。。。
在线时间402 小时
芯币2174 枚
TA的帖子TA的资源
一粒金砂(中级), 积分 86, 距离下一级还需 114 积分
一粒金砂(中级), 积分 86, 距离下一级还需 114 积分
把配置代码贴上来看看,自己做的24l01的电路吗?
宝马/路虎LPC1768、STM32开发板
在线时间4 小时
TA的帖子TA的资源
一粒金砂(中级), 积分 6, 距离下一级还需 194 积分
一粒金砂(中级), 积分 6, 距离下一级还需 194 积分
买的板子,DSP的电路是我自己做的。程序是用C2000的例程和网上找的430的程序结合改的。然后就是我用的是自带的SPI,数据是8位写,它自带的SPI是16位,写数就得这么写。。程序比较乱,谢谢您了。
#include &DSP28x_Project.h&& &&&// Device Headerfile and Examples Include File
// Prototype statements for functions found within this file.
// interrupt void ISRTimer2(void);
void delay_loop(void);
void spi_xmit(Uint16 a);
void spi_fifo_init(void);
void spi_init(void);
void delay_loop1(long b);
void error(void);
void init_NRF24L01(void);
void nRF24L01_TxPacket();
Uint16 send_
void transmit(Uint16*txbuf,Uint16 p);
void transmit2(Uint16 j,Uint16 k);
void transmit_r(Uint16 l);
void transmit_r32(Uint16*rx_buf);
void set_24l01();
Uint16 fla1;
Uint16 fla2;
Uint16 fla3;
Uint16 f1;
Uint16 f2;
Uint16 f3;
Uint16 flag1;
Uint16 flag2;
Uint16 receive1;
Uint16 receive2;
Uint16 receive3;
Uint16 dump[4];
volatile struct SPIFFTX_BITS S
volatile struct SPISTS_BITS SpistsaB
#define RF24L01_CE_0 GpioDataRegs.GPACLEAR.bit.GPIO12=1
#define RF24L01_CE_1 GpioDataRegs.GPASET.bit.GPIO12=1
#define TX_ADR_WIDTH& & 5& && & & & // 5 uints TX address width
#define RX_ADR_WIDTH& & 5& && & & & // 5 uints RX address width
#define TX_PLOAD_WIDTH&&32 & & & & // 20 uints TX payload
#define RX_PLOAD_WIDTH&&32 & & & & // 20 uints TX payload
char TxBuf[32];
char tx_buf[32];
Uint16&&TEST1[6]={0x0,0xfa00,0xff00,0xa000,0xaa00};
Uint16&&TEST2[12]={0x0,0xfa00,0xff00,0xa000,0xaa00,0x0,0xfa00,0xff00,0xa000,0xaa00};
Uint16&&TEST3[18]=
{0x0,0xfa00,0xff00,0xa000,0xaa00,0x0,0xfa00,0xff00,0xa000,0xaa00,0x0,0xfa00,0xff00,0xa000,0xaa00};
Uint16&&TEST4[24]=
{0x0,0xfa00,0xff00,0xa000,0xaa00,0x0,0xfa00,0xff00,0xa000,0xaa00,0x0,0xfa00,0xff00,0xa000,0xaa00,0x0
,0xfa00,0xff00,0xa000,0xaa00};
char TX_ADDRESS[TX_ADR_WIDTH]= {0x0,0x0,0x0100};& & & & //本地地址
char RX_ADDRESS[RX_ADR_WIDTH]= {0x0,0x0,0x0100};& & & & //接收地址
Uint16&&TXADD[6]={0x0,0x0,0x0};
Uint16&&RXADD[6]={0x2a00,0x0,0x0,0x0100};
Uint16&&TXADD1[6]={0x2a00,0x0,0x0,0x0100};
Uint16&&RXBUF[32];
Uint16&&TEST[32]=
{0xaa00,0xf000,0xfa00,0xff00,0xa000,0xaa00,0x0,0xfa00,0xff00,0xa000,0xaa00,0x0,0xfa00,0xff00,0xa000,0xaa00,0x0
,0xfa00,0xff00,0xa000,0xaa00,0x0,0xfa00,0xff00,0xa000,0xaa00,0x0};
Uint16&&TXADD2[33]=
{0xa000,0x0,0xfa00,0xff00,0xa000,0xaa00,0x0,0xfa00,0xff00,0xa000,0xaa00,0x0,0xfa00,0xff00,0xa000,0xaa00,0x1000
,0xf000,0xfa00,0xff00,0xa000,0xaa00,0x0,0xfa00,0xff00,0xa000,0xaa00,0x0};
Uint16 TXADD3[3]={0xa000,0x1000,0xff00};
//***************************************NRF24L01寄存器指令*******************************************************
#define READ_REG& && &&&0x0000&&& & & & // 读寄存器指令
#define WRITE_REG& && & 0x2000 & & & & // 写寄存器指令
#define RD_RX_PLOAD& &&&0x6100&&& & & & // 读取接收数据指令
#define WR_TX_PLOAD& &&&0xA000&&& & & & // 写待发数据指令
#define FLUSH_TX& && &&&0xE100 & & & & // 冲洗发送 FIFO指令
#define FLUSH_RX& && &&&0xE200&&& & & & // 冲洗接收 FIFO指令
#define REUSE_TX_PL& &&&0xE300&&& & & & // 定义重复装载数据指令
#define NOP& && && && & 0xFF00&&& & & & // 保留
//*************************************SPI(nRF24L01)寄存器地址****************************************************
#define CONFIG& && && & 0x0000&&// 配置收发状态,CRC校验模式以及收发状态响应方式
#define EN_AA& && && &&&0x0100&&// 自动应答功能设置
#define EN_RXADDR& && & 0x0200&&// 可用信道设置
#define SETUP_AW& && &&&0x0300&&// 收发地址宽度设置
#define SETUP_RETR& && &0x0400&&// 自动重发功能设置
#define RF_CH& && && &&&0x0500&&// 工作频率设置
#define RF_SETUP& && &&&0x0600&&// 发射速率、功耗功能设置
#define STATUS& && && & 0x0700&&// 状态寄存器
#define OBSERVE_TX& && &0x0800&&// 发送监测功能
#define CD& && && && &&&0x0900&&// 地址检测
#define RX_ADDR_P0& && &0x0A00&&// 频道0接收数据地址
#define RX_ADDR_P1& && &0x0B00&&// 频道1接收数据地址
#define RX_ADDR_P2& && &0x0C00&&// 频道2接收数据地址
#define RX_ADDR_P3& && &0x0D00&&// 频道3接收数据地址
#define RX_ADDR_P4& && &0x0E00&&// 频道4接收数据地址
#define RX_ADDR_P5& && &0x0F00&&// 频道5接收数据地址
#define TX_ADDR& && && &0x1000&&// 发送地址寄存器
#define RX_PW_P0& && &&&0x1100&&// 接收频道0接收数据长度
#define RX_PW_P1& && &&&0x1200&&// 接收频道0接收数据长度
#define RX_PW_P2& && &&&0x1300&&// 接收频道0接收数据长度
#define RX_PW_P3& && &&&0x1400&&// 接收频道0接收数据长度
#define RX_PW_P4& && &&&0x1500&&// 接收频道0接收数据长度
#define RX_PW_P5& && &&&0x1600&&// 接收频道0接收数据长度
#define FIFO_STATUS& &&&0x1700&&// FIFO栈入栈出状态寄存器设置
void main(void)
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the DSP2802x_SysCtrl.c file.
& &InitSysCtrl();
// Step 2. Initalize GPIO:
// This example function is found in the DSP2802x_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
// InitGpio();&&// Skipped for this example
// Setup only the GP I/O only for SPI-A functionality
// This function is found in DSP2802x_Spi.c
& &InitSpiaGpio();
// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
// Initialize PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the DSP2802x_PieCtrl.c file.
& &InitPieCtrl();
// Disable CPU interrupts and clear all CPU interrupt flags:
& &IER = 0x0000;
& &IFR = 0x0000;
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example.&&This is useful for debug purposes.
// The shell ISR routines are found in DSP2802x_DefaultIsr.c.
// This function is found in DSP2802x_PieVect.c.
& &InitPieVectTable();
// Step 4. Initialize all the Device Peripherals:
// This function is found in DSP2802x_InitPeripherals.c
// InitPeripherals(); // Not required for this example
& & spi_fifo_init();& & & && &// Initialize the Spi FIFO
& & spi_init();& & & & & & & && &// init SPI
& & EALLOW;
& &&&SpiaRegs.SPICTL.bit.TALK=1;
& &&&EDIS;
&&GpioCtrlRegs.GPAMUX1.bit.GPIO12=0;
&&GpioCtrlRegs.GPADIR.bit.GPIO12=1;
// Step 5. User specific code:
// Interrupts are not used in this example.
set_24l01();
&&for (;;)
& & & && &transmit2(WRITE_REG+STATUS,0XFF00);
& & & && &nRF24L01_TxPacket();
& & & && &transmit_r(STATUS);
& & & && &f2=receive2;
& & & && & transmit_r(STATUS);
& & & && &&&send_flag=receive2&0x0020;
& & & && && &delay_loop1(2000);
// Step 7. Insert all local Interrupt Service Routines (ISRs) and functions here:
void delay_loop1(long b)
& & long& && &i;
& & for (i = 0; i & i++) {}
void delay_loop()
& & long& && &i;
& & for (i = 0; i & 1000000; i++) {}
void error(void)
& & asm(&& &&&ESTOP0&);& & & & & & & & & & & & & & & & & & & & & & & & // Test failed!! Stop!
& & for (;;);
void spi_init()
& & & &&&SpiaRegs.SPICCR.all =0x0007;& & & && && && && &&&// Reset on, rising edge, 16-bit char bits
& & & & SpiaRegs.SPICTL.all =0x000E;& & & & & & & & & && && &// Enable master mode, normal phase,
& && && && && && && && && && && && && && && && & // enable talk, and SPI int disabled.
& & & & SpiaRegs.SPIBRR =0x001F;
& & SpiaRegs.SPICCR.all =0x0087;& & & & & & & && && && & // Relinquish SPI from Reset
& & SpiaRegs.SPIPRI.bit.FREE = 1;& && && && && & // Set so breakpoints don't disturb xmission
void spi_xmit(Uint16 a)
& & SpiaRegs.SPITXBUF=a;
void spi_fifo_init()
// Initialize SPI FIFO registers
& & SpiaRegs.SPIFFTX.all=0xE040;
& & SpiaRegs.SPIFFRX.all=0x2044;
& & SpiaRegs.SPIFFCT.all=0x0;
//===========================================================================
// No more.
//===========================================================================
void init_NRF24L01(void)
& & & & RF24L01_CE_0 ;
& & & & delay_loop1(2000);
& & & & transmit(TXADD,6);// 写本地地址
& & & & transmit(RXADD,6); // 写接收端地址
& & & & transmit2(WRITE_REG + EN_AA,0x0000);// 频道0自动 ACK应答允许
& & & & transmit2(WRITE_REG + EN_RXADDR,0x0100); // 允许接收地址只有频道0,如果需要多频道可以参考Page21
& & transmit2(WRITE_REG + RF_CH,0);// 设置信道工作为2.4GHZ,收发必须一致
& & transmit2(WRITE_REG + RX_PW_P0,0x0200); //设置接收数据长度,本次设置为32字节
& & transmit2(WRITE_REG + SETUP_RETR,0x0000);
& & & & transmit2(WRITE_REG + RF_SETUP,0x0700);&&//设置发射速率为1MHZ,发射功率为最大值0dB
& & & & transmit2(WRITE_REG + CONFIG,0x0E00);// IRQ收发完成中断响应,16位CRC ,主接收}
void nRF24L01_TxPacket(void)
& & & &&&RF24L01_CE_0 ;
& & & &&&transmit(TXADD1,6);// 装载接收地址
& & & &&&transmit(TXADD2,33); // 装载数据
& & & &&&transmit2(WRITE_REG + CONFIG,0x3E00);//IRQ收发完成中断响应,16位CRC ,发送
& & & &&&transmit_r(STATUS);
& & & &&&fla1=receive2;
& & & &&&RF24L01_CE_1;
& & & &&&delay_loop1(60);
& & & &&&RF24L01_CE_0 ;
& & & &&&transmit_r(STATUS);
& & & &&&& & & &&&fla3=receive2;
void transmit(Uint16*txbuf,Uint16 p)
& & & & f=0;
& & & && & for (f = 0; f & f++)
& & & && && & & & & & & &&&{
& & & && && & & && && &spi_xmit(txbuf[f]);
& & & && && & & && & for (;;)
& & & && && & {
& & & && && & flag2=SpiaRegs.SPIFFTX.bit.TXFFST;
& & & && && & if(flag2==0)
& & & && && & {
& & & && && & flag2=1;
& & & && && &
& & & && && & }
& & & && && & }
& & & && & delay_loop1(2000);
void transmit2(Uint16 j,Uint16 k)
& & & && && & & && & spi_xmit(j);
& & & && && &&&spi_xmit(k);
& & & && && & & && && & & && & for (;;)
& & & && && & & && && & {
& & & && && & & && && & & & & & & &&&flag2=SpiaRegs.SPIFFTX.bit.TXFFST;
& & & && && & & && && & if(flag2==0)
& & & && && & & && && & {
& & & && && & & && &&&& & & & flag2=1;
& & & && && & & && && &
& & & && && & & && && & }
& & & && && & & && && & }
& & & && & delay_loop1(2000);
void transmit_r(Uint16 l)
& & & && & for (i=0;i&4;i++)
& & & & & & & && && & & && && & {
& & & & & & & & & & & && && & & && && & flag1=SpiaRegs.SPIFFRX.bit.RXFFST;
& & & & & & & & & & & && && & & && && & if(flag1!=0)
& & & & & & & & & & & && && & & && && & {
& & & & & & & & & & & && && & & && & & & & &&&dump[i]=SpiaRegs.SPIRXBUF;
& & & & & & & & & & & && && & & && && & }
& & & & & & & & & & & && && & & && && & else
& & & & & & & & & & & && && & & && && & {
& & & & & & & & & & & && && & & && &&&& & & && &
& & & & & & & & & & & && && & & && && & }
& & & & & & & & & & & && && & & && && & }
& & & && & spi_xmit(l);
& & & && & spi_xmit(0xff00);
& & & && & for (;;)
& & & && && & & && && & {
& & & & & & & && &flag2=SpiaRegs.SPIFFTX.bit.TXFFST;
& & & && && & & && && & if(flag2==0)
& & & && && & & && && & {
& & & && && & & && && &flag2=1;
& & & && && & & && && &
& & & && && & & && && & }
& & & && && & & && && & }
& & & && &while(SpiaRegs.SPIFFRX.bit.RXFFST !=2) { }
& & & && &receive1=SpiaRegs.SPIRXBUF;
& & & && &receive2=SpiaRegs.SPIRXBUF;
& & & && &//receive3=SpiaRegs.SPIRXBUF;
& & & && & delay_loop1(2000);
void SetRX_Mode(void)
& & & & RF24L01_CE_0;
& & & & transmit2(WRITE_REG + CONFIG, 0x0f); // IRQ收发完成中断响应,16位CRC,主接收
& & & & RF24L01_CE_1;
& & & & delay_loop1(2000); //注意不能太小
//******************************************************************************************************/
//函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
//功能:数据读取后放如rx_buf接收缓冲区中
//******************************************************************************************************/
void nRF24L01_RxPacket()
& & & & RX_flag=0;
& & & & transmit_r(STATUS); // 读取状态寄存其来判断数据接收状况
& & & & sta=receive2;
& & & & if(sta&0x4000) // 判断是否接收到数据
& & & & RF24L01_CE_0 ; //SPI使能
//& & & & SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH); // read receive payload from RX_FIFO buffer
& & & & spi_xmit(RD_RX_PLOAD);
& & & & transmit_r32(RXBUF);
& & & & RX_flag =1; //读取数据完成标志
& & & & transmit2(WRITE_REG+STATUS,sta); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志
void transmit_r32(Uint16*rx_buf)
Uint16 i,j;
& & & && & for (i=0;i&4;i++)
& & & & & & & && && & & && && & {
& & & & & & & & & & & && && & & && && & flag1=SpiaRegs.SPIFFRX.bit.RXFFST;
& & & & & & & & & & & && && & & && && & if(flag1!=0)
& & & & & & & & & & & && && & & && && & {
& & & & & & & & & & & && && & & && & & & & &&&dump[i]=SpiaRegs.SPIRXBUF;
& & & & & & & & & & & && && & & && && & }
& & & & & & & & & & & && && & & && && & else
& & & & & & & & & & & && && & & && && & {
& & & & & & & & & & & && && & & && &&&& & & && &
& & & & & & & & & & & && && & & && && & }
& & & & & & & & & & & && && & & && && & }
& & & && & for (j=0;j&32;j++)
& & & && & {
& & & & & & & && &spi_xmit(0xff00);
& & & & & & & && &for(;;)
& & & && && & & && && & {
& & & && && & & && && & flag1=SpiaRegs.SPIFFTX.
& & & && && & & && && & flag2=flag1&0x1F;
& & & && && & & && && & if(flag2==0)
& & & && && & & && && & {
& & & && && & & && && &flag2=1;
& & & && && & & && && &
& & & && && & & && && & }
& & & && && & & && && & }
& & & && &while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }
& & & & & & & &&&rx_buf[i]=SpiaRegs.SPIRXBUF;
& & & && &//receive3=SpiaRegs.SPIRXBUF;
& & & && &delay_loop1(2000);
void LEDSET()
& & & && & EALLOW;
& & & && & GpioCtrlRegs.GPAMUX1.bit.GPIO5=0;
& & & && & GpioCtrlRegs.GPBMUX1.bit.GPIO34=0;
& & & && & GpioCtrlRegs.GPADIR.bit.GPIO5=1;
& & & && & GpioCtrlRegs.GPBDIR.bit.GPIO34=1;
& & & && & EDIS;
void LED_blink()
& & & && && && && &GpioDataRegs.GPASET.bit.GPIO5=1;
& && & & & & & & & & & & && & GpioDataRegs.GPBSET.bit.GPIO34=1;
& && & & & & & & && && &&&delay_loop1(200000);
& && & & & & & & && && &&&GpioDataRegs.GPACLEAR.bit.GPIO5=1;
& && & & & & & & && && &&&GpioDataRegs.GPBCLEAR.bit.GPIO34=1;
& && & & & & & & && && &&&delay_loop1(200000);
void set_24l01()
& & & & RF24L01_CE_0 ;
& & & & delay_loop1(2000);
& & & & transmit(TXADD,6);// 写本地地址
& & & & transmit(RXADD,6); // 写接收端地址
& & & & transmit2(WRITE_REG + EN_AA,0x0000);// 频道0自动 ACK应答允许
& & & & transmit2(WRITE_REG + EN_RXADDR,0x0100); // 允许接收地址只有频道0,如果需要多频道可以参考Page21
& & & & transmit2(WRITE_REG + SETUP_AW,0x0300);
& & & & transmit2(WRITE_REG + SETUP_RETR,0x0000);
& & transmit2(WRITE_REG + RF_CH,0);// 设置信道工作为2.4GHZ,收发必须一致
& & transmit2(WRITE_REG + RX_PW_P0,0x2000); //设置接收数据长度,本次设置为32字节
& & transmit2(WRITE_REG + RX_PW_P1,0x0000);
& & transmit2(WRITE_REG + RX_PW_P2,0x0000);
& & transmit2(WRITE_REG + RX_PW_P3,0x0000);
& & transmit2(WRITE_REG + RX_PW_P4,0x0000);
& & transmit2(WRITE_REG + RX_PW_P5,0x0000);
& & & & transmit2(WRITE_REG + RF_SETUP,0x0700);&&//设置发射速率为1MHZ,发射功率为最大值0dB
& & & & transmit2(WRITE_REG + CONFIG,0x0E00);// IRQ收发完成中断响应,16位CRC ,主接收}
在线时间4 小时
TA的帖子TA的资源
一粒金砂(中级), 积分 6, 距离下一级还需 194 积分
一粒金砂(中级), 积分 6, 距离下一级还需 194 积分
有些备注的字和我改程序不一样。因为一直在调试所以有些乱。这是发的。收的程序就是连载波都收不到,就一直读09寄存器。一直读回来的是0.。。
Powered by
逛了这许久,何不进去瞧瞧?STM32和NRF24L01实现无线传输
由于当时写的时候很白菜,h文件和c文件放一块了,不过加到工程里时也这么一段代码,无线模块就能用了,虽不规范,但用起来还凑合。单片机用的是STM32104VC,无线模块是淘宝买的NRF24L01,简单实用,效果不错。
配置文件里加上时钟的配置
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);
使用的时候直接在主函数里设置TXMode()或者RXMode();然后调用函数u8 NRF24L01_TxPacket(u8
*txbuf)或者
u8 NRF24L01_RxPacket(u8 *txbuf)即可。
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//NRF24L01寄存器操作命令
#define READ_REG & &
&//读配置寄存器,低5位为寄存器地址
#define WRITE_REG & &
& 0x20 &//写配置寄存器,低5位为寄存器地址
#define RD_RX_PLOAD & & 0x61
&//读RX有效数据,1~32字节
#define WR_TX_PLOAD & & 0xA0
&//写TX有效数据,1~32字节
#define FLUSH_TX & &
& &0xE1 &//清除TX
FIFO寄存器.发射模式下用
#define FLUSH_RX & &
& &0xE2 &//清除RX
FIFO寄存器.接收模式下用
#define REUSE_TX_PL & & 0xE3
&//重新使用上一包数据,CE为高,数据包被不断发送.
#define NOP & &
& 0xFF &//空操作,可以用来读状态寄存器
//SPI(NRF24L01)寄存器地址
#define CONFIG & &
&//配置寄存器地址;bit0:1接收模式,0发射模式;bit1:电选择;bit2:CRC模式;bit3:CRC使能;
//bit4:中断MAX_RT(达到最大重发次数中断)使能;bit5:中断TX_DS使能;bit6:中断RX_DR使能
#define EN_AA & &
& & & 0x01
&//使能自动应答功能 &bit0~5,对应通道0~5
#define EN_RXADDR & &
&//接收地址允许,bit0~5,对应通道0~5
#define SETUP_AW & &
&//设置地址宽度(所有数据通道):bit1,0:00,3字节;01,4字节;02,5字节;
#define SETUP_RETR & &
&//建立自动重发;bit3:0,自动重发计数器;bit7:4,自动重发延时
250*x+86us
#define RF_CH & &
& & & 0x05
&//RF通道,bit6:0,工作通道频率;
#define RF_SETUP & &
&//RF寄存器;bit3:传输速率(0:1Mbps,1:2Mbps);bit2:1,发射功率;bit0:低噪声放大器增益
#define STATUS & &
&//状态寄存器;bit0:TX
FIFO满标志;bit3:1,接收数据通道号(最大:6);bit4,达到最多次重发
//bit5:数据发送完成中断;bit6:接收数据中断;
#define MAX_TX & 0x10
&//达到最大发送次数中断
#define TX_OK & 0x20
&//TX发送完成中断
#define RX_OK & 0x40
&//接收到数据中断
#define OBSERVE_TX & &
&//发送检测寄存器,bit7:4,数据包丢失计数器;bit3:0,重发计数器
#define CD & &
&//载波检测寄存器,bit0,载波检测;
#define RX_ADDR_P0 & &
&//数据通道0接收地址,最大长度5个字节,低字节在前
#define RX_ADDR_P1 & &
&//数据通道1接收地址,最大长度5个字节,低字节在前
#define RX_ADDR_P2 & &
&//数据通道2接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等;
#define RX_ADDR_P3 & &
&//数据通道3接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等;
#define RX_ADDR_P4 & &
&//数据通道4接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等;
#define RX_ADDR_P5 & &
&//数据通道5接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等;
#define TX_ADDR & &
&//发送地址(低字节在前),ShockBurstTM模式下,RX_ADDR_P0与此地址相等
#define RX_PW_P0 & &
&//接收数据通道0有效数据宽度(1~32字节),设置为0则非法
#define RX_PW_P1 & &
&//接收数据通道1有效数据宽度(1~32字节),设置为0则非法
#define RX_PW_P2 & &
&//接收数据通道2有效数据宽度(1~32字节),设置为0则非法
#define RX_PW_P3 & &
&//接收数据通道3有效数据宽度(1~32字节),设置为0则非法
#define RX_PW_P4 & &
&//接收数据通道4有效数据宽度(1~32字节),设置为0则非法
#define RX_PW_P5 & &
&//接收数据通道5有效数据宽度(1~32字节),设置为0则非法
#define FIFO_STATUS & & 0x17
&//FIFO状态寄存器;bit0,RX FIFO寄存器空标志;bit1,RX
FIFO满标志;bit2,3,保留
& & & //bit4,TX
FIFO空标志;bit5,TX FIFO满标志;bit6,1,循环发送上一数据包.0,不循环;
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//24L01片选信号
#define CE_H() & GPIO_SetBits(GPIOB,
GPIO_Pin_12)&
#define CE_L() & GPIO_ResetBits(GPIOB,
GPIO_Pin_12)
//SPI片选信号
#define CSN_H() &GPIO_SetBits(GPIOC,
GPIO_Pin_4)
#define CSN_L() &GPIO_ResetBits(GPIOC,
GPIO_Pin_4)
//IRQ主机数据输入
//#define NRF24L01_IRQ
&GPIO_ReadInputData(GPIOC,GPIO_Pin_5)
//24L01发送接收数据宽度定义
#define TX_ADR_WIDTH & &5
& //5字节的地址宽度
#define RX_ADR_WIDTH & &5
& //5字节的地址宽度
#define TX_PLOAD_WIDTH &3
&//32字节的用户数据宽度
#define RX_PLOAD_WIDTH &3
&//32字节的用户数据宽度
void NRF24L01_Init(void);//初始化
void RX_Mode(void);//配置为接收模式
void TX_Mode(void);//配置为发送模式
u8 NRF24L01_Write_Buf(u8 reg, u8 *pBuf, u8 u8s);//写数据区
u8 NRF24L01_Read_Buf(u8 reg, u8 *pBuf, u8 u8s);//读数据区
u8 NRF24L01_Read_Reg(u8 reg); //读寄存器
u8 NRF24L01_Write_Reg(u8 reg, u8 value);//写寄存器
u8 NRF24L01_Check(void);//检查24L01是否存在
u8 NRF24L01_TxPacket(u8 *txbuf);//发送一个包的数据
u8 NRF24L01_RxPacket(u8 *rxbuf);//接收一个包的数据
//#include "stm32f10x_spi.h"
//#include "NRF24L01.h"
const u8 TX_ADDRESS[TX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01};
//发送地址
const u8 RX_ADDRESS[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01};
//发送地址
// SPI总线速度设置&
#define SPI_SPEED_2 & 0
#define SPI_SPEED_8 & 1
#define SPI_SPEED_16 &2
#define SPI_SPEED_256 3
void SPI2_SetSpeed(u8 SpeedSet)
&SPI2-&CR1&=0XFFC7;//Fsck=Fcpu/256
&if(SpeedSet==SPI_SPEED_2)//二分频
SPI2-&CR1|=0&&3;//Fsck=Fpclk/2=36Mhz
}else if(SpeedSet==SPI_SPEED_8)//八分频&
SPI2-&CR1|=2&&3;//Fsck=Fpclk/8=9Mhz
}else if(SpeedSet==SPI_SPEED_16)//十六分频
SPI2-&CR1|=3&&3;//Fsck=Fpclk/16=4.5Mhz
}else //256分频
SPI2-&CR1|=7&&3;
//Fsck=Fpclk/256=281.25Khz 低速模式
SPI2-&CR1|=1&&6;
//SPI设备使能
u8 SPI_ReadWriteByte(u8 data)
& & u8 retry=0;
while((SPI2-&SR&1&&1)==0)//等待发送区空
if(retry&200)return 0;
&//发送一个byte&
while((SPI2-&SR&1&&0)==0)
//等待接收完一个byte &
if(retry&200)return 0;
return SPI2-&DR; &
&//返回收到的数据
void SPI2_Init()
& &SPI_InitTypeDef
&SPI_InitS
& &SPI_I2S_DeInit(SPI2);
& &SPI_Cmd(SPI2, DISABLE);
//必须先禁用,才能改变MODE
&SPI_InitStructure.SPI_Direction =
SPI_Direction_2Lines_FullD &//两线全双工
&SPI_InitStructure.SPI_Mode = SPI_Mode_M
& & & //主
&SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
& & &//8位
&SPI_InitStructure.SPI_CPOL = SPI_CPOL_L
&//CPOL=0 时钟悬空低
&SPI_InitStructure.SPI_CPHA = SPI_CPHA_1E
& & & //CPHA=0
数据捕获第1个
& &SPI_InitStructure.SPI_NSS
= SPI_NSS_S & &
& &//软件NSS
&SPI_InitStructure.SPI_BaudRatePrescaler =
SPI_BaudRatePrescaler_4 ; //256分频
&SPI_InitStructure.SPI_FirstBit =
SPI_FirstBit_MSB; & &
&//高位在前
&SPI_InitStructure.SPI_CRCPolynomial = 7;
& &SPI_Init(SPI2,
&SPI_InitStructure);
& &SPI_Cmd(SPI2,
& &SPI_ReadWriteByte(0xff);
& //启动传输
void &NRF24L01_Init(void)
// & GPIO_SetBits(GPIOB,GPIO_Pin_12);
// & GPIO_SetBits(GPIOC,GPIO_Pin_4);
// & GPIO_SetBits(GPIOC,GPIO_Pin_5);
& &SPI2_Init();
//初始化SPI
& &CE_L();
& &//使能24L01
& &CSN_H();
&//SPI片选取消
u8 NRF24L01_Check(void)
u8 buf[5]={0XA5,0XA5,0XA5,0XA5,0XA5};
SPI2_SetSpeed(SPI_SPEED_8); //spi速度为9Mhz(24L01的最大SPI时钟为10Mhz)
NRF24L01_Write_Buf(WRITE_REG+TX_ADDR,buf,5);//写入5个字节的地址.
NRF24L01_Read_Buf(TX_ADDR,buf,5); //读出写入的地址
for(i=0;i&5;i++)if(buf[i]!=0XA5)
if(i!=5)return 1;//检测24L01错误
return 0; //检测到24L01
u8 NRF24L01_Write_Reg(u8 reg,u8 value)
CSN_L(); & &
& &//使能SPI传输
& status=SPI_ReadWriteByte(reg);
&//发送寄存器号&
& SPI_ReadWriteByte(value);
& //写入寄存器的值
& CSN_H(); &
&//禁止SPI传输
return(status); &
&//返回状态值
u8 NRF24L01_Read_Reg(u8 reg)
u8 reg_ & &
& CSN_L(); &
& &//使能SPI传输
& SPI_ReadWriteByte(reg); &
//发送寄存器号
reg_val=SPI_ReadWriteByte(0XFF);//读取寄存器内容
& CSN_H(); &
& &//禁止SPI传输 &
& return(reg_val); &
&//返回状态值
u8 NRF24L01_Read_Buf(u8 reg,u8 *pBuf,u8 len)
u8 status,u8_ & &
& CSN_L(); &
& //使能SPI传输
& status=SPI_ReadWriteByte(reg);
//发送寄存器值(位置),并读取状态值&
for(u8_ctr=0;u8_ctr&u8_ctr++)
pBuf[u8_ctr]=SPI_ReadWriteByte(0XFF);//读出数据
& CSN_H(); &
& //禁止SPI传输
& //返回读到的状态值
u8 NRF24L01_Write_Byte(u8 reg, u8 pBuf)
& CSN_L(); &
& &//使能SPI传输
& status =
SPI_ReadWriteByte(reg);//发送寄存器值(位置),并读取状态值
SPI_ReadWriteByte(pBuf); & &
& &//写入数据
& CSN_H(); &
& &//关闭SPI传输
& &//返回读到的状态值
u8 NRF24L01_Write_Buf(u8 reg, u8 *pBuf, u8 len)
u8 status,u8_ & &
& CSN_L(); &
& &//使能SPI传输
& status =
SPI_ReadWriteByte(reg);//发送寄存器值(位置),并读取状态值
& for(u8_ctr=0; u8_ctr&
SPI_ReadWriteByte(*pBuf++); &
& //写入数据 &
& CSN_H(); &
& &//关闭SPI传输
& &//返回读到的状态值
u8 NRF24L01_TxPacket(u8 *txbuf)
SPI2_SetSpeed(SPI_SPEED_8);//spi速度为9Mhz(24L01的最大SPI时钟为10Mhz)
NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);//写数据到TX BUF
& CE_H(); &
& //启动发送
while(GPIOC-&IDR&1&&5);
//等待发送完成
sta=NRF24L01_Read_Reg(STATUS); &//读取状态寄存器的值
NRF24L01_Write_Reg(WRITE_REG+STATUS,sta);
//清除TX_DS或MAX_RT中断标志
if(sta&MAX_TX)//达到最大重发次数
NRF24L01_Write_Reg(FLUSH_TX,0xff);//清除TX
FIFO寄存器&
return MAX_TX;&
if(sta&TX_OK)//发送完成
return TX_OK;
return 0//其他原因发送失败
u8 NRF24L01_RxPacket(u8 *rxbuf)
SPI2_SetSpeed(SPI_SPEED_8); //spi速度为9Mhz(24L01的最大SPI时钟为10Mhz)
sta=NRF24L01_Read_Reg(STATUS); &//读取状态寄存器的值
NRF24L01_Write_Reg(WRITE_REG+STATUS,sta);
//清除TX_DS或MAX_RT中断标志
if(sta&RX_OK)//接收到数据
NRF24L01_Read_Buf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//读取数据
NRF24L01_Write_Reg(FLUSH_RX,0xff);//清除RX
FIFO寄存器&
return 0;&
return 1;//没收到任何数据
void RX_Mode(void)
NRF24L01_Write_Buf(WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH);//写RX节点地址
& NRF24L01_Write_Reg(WRITE_REG+EN_AA,0x01);
//使能通道0的自动应答 & &
NRF24L01_Write_Reg(WRITE_REG+EN_RXADDR,0x01); &
//使能通道0的接收地址 & &
& NRF24L01_Write_Reg(WRITE_REG+RF_CH,40);
&//设置RF通信频率 &
NRF24L01_Write_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//选择通道0的有效数据宽度
NRF24L01_Write_Reg(WRITE_REG+RF_SETUP,0x0f); &
&//设置TX发射参数,0db增益,2Mbps,低噪声增益开启
& NRF24L01_Write_Reg(WRITE_REG+CONFIG, 0x0f);
//配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式&
& CE_H(); &
&//CE为高,进入接收模式&
void TX_Mode(void)
CE_L(); & &
NRF24L01_Write_Buf(WRITE_REG+TX_ADDR,(u8*)TX_ADDRESS,TX_ADR_WIDTH);//写TX节点地址&
NRF24L01_Write_Buf(WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH);
//设置TX节点地址,主要为了使能ACK &
& NRF24L01_Write_Reg(WRITE_REG+EN_AA,0x01);
& & //使能通道0的自动应答
NRF24L01_Write_Reg(WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址
NRF24L01_Write_Reg(WRITE_REG+SETUP_RETR,0x1a);//设置自动重发间隔时间:500us +
86最大自动重发次数:10次
& NRF24L01_Write_Reg(WRITE_REG+RF_CH,40);
//设置RF通道为40
NRF24L01_Write_Reg(WRITE_REG+RF_SETUP,0x0f);
&//设置TX发射参数,0db增益,2Mbps,低噪声增益开启
& NRF24L01_Write_Reg(WRITE_REG+CONFIG,0x0e);
&//配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式,开启所有中断
CE_H(); //CE为高,10us后启动发送
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

我要回帖

更多关于 nrf24l01 的文章

 

随机推荐