打印

nrf24l01+

[复制链接]
1368|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
有没有使用过NRF24L01+的大神啊?
小弟调试这个模块两周了就是搞不定啊。我用的是TMS320F28027,自带的SPI写的程序。
网上大部分是模拟SPI,我使用的自带的。
现在就是我给可以写值的寄存器写值是没问题的。例如我给CONFIG写0f读回来的也是0f。
问题是我现在发布出去,如果把EN_AA关闭后,STATUS的值可以从默认的14变到46,
但是接收端是没有反应的。
NRF24L01+有一个载波检测功能,
就是09号寄存器,我在接收端发现竟然连这个寄存器都无法检测到载波信号。
我真的是陷入绝望了。已经两周没睡好觉了。求求用过的大神指点一二。我的qq740301961.
跪谢了~~~~

相关帖子

沙发
电子科技哪家强|  楼主 | 2015-4-11 16:47 | 只看该作者
买的板子,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_flag;


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 sta;
Uint16 f;
Uint16 receive1;
Uint16 receive2;
Uint16 receive3;
Uint16 dump[4];
volatile struct SPIFFTX_BITS Spifftx;
volatile struct SPISTS_BITS SpistsaBits;
#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]={0x1000,0xf000,0xfa00,0xff00,0xa000,0xaa00};
Uint16  TEST2[12]={0x1000,0xf000,0xfa00,0xff00,0xa000,0xaa00,0x1000,0xf000,0xfa00,0xff00,0xa000,0xaa00};
Uint16  TEST3[18]=

{0x1000,0xf000,0xfa00,0xff00,0xa000,0xaa00,0x1000,0xf000,0xfa00,0xff00,0xa000,0xaa00,0x1000,0xf000,0xfa00,0xff00,0xa000,0xaa00};
Uint16  TEST4[24]=

{0x1000,0xf000,0xfa00,0xff00,0xa000,0xaa00,0x1000,0xf000,0xfa00,0xff00,0xa000,0xaa00,0x1000,0xf000,0xfa00,0xff00,0xa000,0xaa00,0x1000,0xf000

,0xfa00,0xff00,0xa000,0xaa00};
char TX_ADDRESS[TX_ADR_WIDTH]= {0x3400,0x4300,0x1000,0x1000,0x0100};        //本地地址
char RX_ADDRESS[RX_ADR_WIDTH]= {0x3400,0x4300,0x1000,0x1000,0x0100};        //接收地址
Uint16  TXADD[6]={0x3000,0x3400,0x4300,0x1000,0x1000,0x0100};
Uint16  RXADD[6]={0x2a00,0x3400,0x4300,0x1000,0x1000,0x0100};
Uint16  TXADD1[6]={0x2a00,0x3400,0x4300,0x1000,0x1000,0x0100};
Uint16  RXBUF[32];
Uint16  TEST[32]=

{0xaa00,0xf000,0xfa00,0xff00,0xa000,0xaa00,0x1000,0xf000,0xfa00,0xff00,0xa000,0xaa00,0x1000,0xf000,0xfa00,0xff00,0xa000,0xaa00,0x1000,0xf000

,0xfa00,0xff00,0xa000,0xaa00,0x1000,0xf000,0xfa00,0xff00,0xa000,0xaa00,0x1000,0xf000};
Uint16  TXADD2[33]=

{0xa000,0x1000,0xf000,0xfa00,0xff00,0xa000,0xaa00,0x1000,0xf000,0xfa00,0xff00,0xa000,0xaa00,0x1000,0xf000,0xfa00,0xff00,0xa000,0xaa00,0x1000

,0xf000,0xfa00,0xff00,0xa000,0xaa00,0x1000,0xf000,0xfa00,0xff00,0xa000,0xaa00,0x1000,0xf000};
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
   DINT;

// 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;

  EALLOW;
  GpioCtrlRegs.GPAMUX1.bit.GPIO12=0;
  GpioCtrlRegs.GPADIR.bit.GPIO12=1;

  EDIS;

// 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 < b; 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 < p; f++)
                           {
                       spi_xmit(txbuf[f]);
                     for (;;)
              {

              flag2=SpiaRegs.SPIFFTX.bit.TXFFST;
              if(flag2==0)
              {
              flag2=1;
              break;
              }
              }
  }
           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;
                        break;
                        }
                        }
           delay_loop1(2000);
}
void transmit_r(Uint16 l)

{
Uint16 i;
           for (i=0;i<4;i++)
                                {
                                        flag1=SpiaRegs.SPIFFRX.bit.RXFFST;

                                        if(flag1!=0)
                                        {
                                              dump[i]=SpiaRegs.SPIRXBUF;
                                        }
                                        else
                                        {
                                                break;
                                        }
                                        }


           spi_xmit(l);

           spi_xmit(0xff00);
           for (;;)
                        {
                  flag2=SpiaRegs.SPIFFTX.bit.TXFFST;
                        if(flag2==0)
                        {
                       flag2=1;
                        break;
                        }
                        }
          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
                                        {
                                                break;
                                        }
                                        }

           for (j=0;j<32;j++)
           {
                  spi_xmit(0xff00);
                  for(;;)
                        {
                        flag1=SpiaRegs.SPIFFTX.all;
                        flag2=flag1&0x1F;
                        if(flag2==0)
                        {
                       flag2=1;
                        break;
                        }
                        }

          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 ,主接收}
}

使用特权

评论回复
板凳
comeon201208| | 2015-4-12 20:29 | 只看该作者
分享的程序很不错的。

使用特权

评论回复
地板
coody| | 2015-4-13 18:06 | 只看该作者
那你也可以先用IO模拟访问看看是否成功,IO模拟访问简单,速度明确。
正常后,再切换到硬件SPI访问、调试。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

3

帖子

0

粉丝