Louis@TL 2019-06-03 10:41 采纳率: 0%
浏览 441

nRF24L01 2.4G收发问题

第一次用这个芯片,博主用的是中断的方式读取状态以及接收数据,发现发送端每次读出来的值是0x1F,说明发送到达了最大发送次数而没有被接收?发送是OK的吗?然而接收端怎么也没有数据打印出来,接收不到任何数据,不知道问题出现在哪里,读写寄存器函数是OK的,求大神指点一下。

#ifdef nRF24l01_EN

#define NRF24L01_TX   0  //发送使能      1:发送      0:接收


#define MOSI_PORT JL_PORTB
#define MOSI_BIT  BIT(1)

#define MISO_PORT JL_PORTB
#define MISO_BIT  BIT(0)

#define SCK_PORT JL_PORTB
#define SCK_BIT  BIT(6)

#define CSN_PORT JL_PORTB
#define CSN_BIT  BIT(3)

#define CE_PORT JL_PORTB
#define CE_BIT  BIT(5)


#define MOSI_SET(x) do{x?(MOSI_PORT->OUT|=MOSI_BIT):(MOSI_PORT->OUT&=~MOSI_BIT);}while(0)
#define CSN_SET(x) do{x?(CSN_PORT->OUT|=CSN_BIT):(CSN_PORT->OUT&=~CSN_BIT);}while(0)
#define CE_SET(x) do{x?(CE_PORT->OUT|=CE_BIT):(CE_PORT->OUT&=~CE_BIT);}while(0)


#define SCK_SET(x) do{x?(SCK_PORT->OUT|=SCK_BIT):(SCK_PORT->OUT&=~SCK_BIT);}while(0)


#define MISO_DAT() (MISO_PORT->IN&MISO_BIT)

uint8_t const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址
uint8_t const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址

void spi_io_init(void)
{
    MOSI_PORT->DIR &= ~MOSI_BIT;
    MISO_PORT->DIR |= MISO_BIT;
    CE_PORT->DIR &= ~CE_BIT;
    CE_PORT->OUT &= ~CE_BIT;
    CSN_PORT->DIR &= ~CSN_BIT;
    CSN_PORT->OUT |= CSN_BIT;
    SCK_PORT->DIR &= ~SCK_BIT;
    SCK_PORT->OUT &= ~SCK_BIT;

}
void inerDelay_us(unsigned char n)
{
    for(;n>0;n--)
        asm("nop");
}

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


uint8_t SPI_Read(uint8_t reg)
{
    uint8_t reg_val;

    CSN_SET(0);                // CSN low, initialize SPI communication...
    SPI_RW(reg);            // Select register to read from..
    reg_val = SPI_RW(0);    // ..then read registervalue
    CSN_SET(1);                // CSN high, terminate SPI communication

    return(reg_val);        // return register value
}
uint8_t SPI_RW_Reg(uint8_t reg, uint8_t value)
{
    uint8_t status;

    CSN_SET(0);                   // CSN low, init SPI transaction
    status = SPI_RW(reg);      // select register
    SPI_RW(value);             // ..and write value to it..
    CSN_SET(1);                  // CSN high again

    return(status);            // return nRF24L01 status uchar
}
uint8_t SPI_Read_Buf(uint8_t reg, uint8_t *pBuf, uint8_t uchars)
{
    uint8_t status,uchar_ctr;

    CSN_SET(0);                             // Set CSN low, init SPI tranaction
    status = SPI_RW(reg);               // Select register to write to and read status uchar

    for(uchar_ctr=0;uchar_ctr<uchars;uchar_ctr++)
        pBuf[uchar_ctr] = SPI_RW(0);    //

    CSN_SET(1);

    return(status);                    // return nRF24L01 status uchar
}
uint8_t SPI_Write_Buf(uint8_t reg, uint8_t *pBuf, uint8_t uchars)
{
    uint8_t status,uchar_ctr;

    CSN_SET(0);           //SPI使能
    status = SPI_RW(reg);
    for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr++) //
        SPI_RW(*pBuf++);
    CSN_SET(1);         //关闭SPI
    return(status);    //
}


void SetRX_Mode(void)
{
    SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, (uint8_t *)RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址
    SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
    SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);           // IRQ收发完成中断响应,16位CRC   ,主接收
}
/*

*/
void nRF24L01_RxPacket(unsigned char* rx_buf)
{
    unsigned char revale=0;
    uint8_t sta=SPI_Read(STATUS);   // 读取状态寄存其来判断数据接收状况
    CE_SET(1);              
//  printf("R:%x ",sta);
    if(sta & BIT(6))                // 判断是否接收到数据
    {
        CE_SET(0);              
        printf("R");
        SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// read receive payload from RX_FIFO buffer
    }
    SPI_RW_Reg(WRITE_REG+STATUS,sta);   //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志

}

void nRF24L01_TxPacket(unsigned char * tx_buf)
{
    //printf("s");

    CE_SET(0);      //StandBy I模式
    SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, (uint8_t *)RX_ADDRESS, RX_ADR_WIDTH); // 装载接收端地址
    SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH);              // 装载数据
    SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);            // IRQ收发完成中断响应,16位CRC,主发送
    CE_SET(1);   //置高CE,激发数据发送
}
void nrf24l01_irq_init(void);

void NRF24L01_RX_Mode(void)
{

} 
/******************************************************************************
 * \par  Description:  
 * \param[in]    NULL
 * \param[out]    NULL
 * \return       NULL
 * \ note:       
 *******************************************************************************/

void init_NRF24L01(void)
{
    spi_io_init();

    nrf24l01_irq_init();

    CE_SET(0);

    SPI_Write_Buf(WRITE_REG + TX_ADDR, (uint8_t *)TX_ADDRESS, TX_ADR_WIDTH);    // 写本地地址
    SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, (uint8_t *)RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址
    SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);      //  频道0自动 ACK应答允许
    SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  //  允许接收地址只有频道0,如果需要多频道可以参考Page21
    SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a);        //   设置重发次数
    SPI_RW_Reg(WRITE_REG + RF_CH, 40);        //   设置信道工作为2.4GHZ,收发必须一致
    SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
    SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);         //设置发射速率为2MHZ,发射功率为最大值0dB
#if (NRF24L01_TX == 0)
    SetRX_Mode();
#endif

}


const u8 send_data[32]={0x55,0x5a,0xa5,0xaa};
u8 rx_buf[32];
void nrf24l01_msg_handler(void)
{
#if (NRF24L01_TX == 0)
    //nRF24L01_RxPacket(rx_buf);
#endif
}
/******************************************************************************
 * \par  Description:  1秒消息处理
 * \param[in]    NULL
 * \param[out]    NULL
 * \return       NULL
 * \ note:       
 *******************************************************************************/
void one_second_handler(void)
{
#if (NRF24L01_TX)
    nRF24L01_TxPacket((u8 *)send_data);
#endif
}
u8 nrf24l01_rx_buf[32];

/******************************************************************************
 * \par  Description:  外部中断服务
 * \param[in]    NULL
 * \param[out]    NULL
 * \return       NULL
 * \ note:       
 *******************************************************************************/
void nrf24l01_isr(void)
{
/*  CE_SET(0);    
    uint8_t sta = SPI_Read(STATUS); // 读取状态寄存其来判断数据接收状况

    printf("%x ",sta);

    SPI_RW_Reg(WRITE_REG+STATUS,sta);   //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志
    if (sta & 0x10){
        CE_SET(1);    // chip enable
        SPI_RW_Reg(WRITE_REG+FLUSH_TX,0xff);
    }*/
    nRF24L01_RxPacket(nrf24l01_rx_buf);

    JL_WAKEUP->CON2 |= BIT(12);//clean pending

}

IRQ_REGISTER(IRQ_PORT_IDX, nrf24l01_isr);
/******************************************************************************
 * \par  Description:  外部中断初始化
 * \param[in]    NULL
 * \param[out]    NULL
 * \return       NULL
 * \ note:       下降沿触发
 *******************************************************************************/
void nrf24l01_irq_init(void)
{

    JL_PORTB->DIR |=BIT(4);
    JL_PORTB->DIE |= BIT(4);
    JL_PORTB->PU |=BIT(4);
    JL_PORTB->PD &=~BIT(4);
    printf("*****nrf24l01_irq_init init***\n");


    JL_WAKEUP->CON0 |= BIT(12);//检查PA8电平触发
    JL_WAKEUP->CON1 |= BIT(12);//下降沿触发

    IRQ_REQUEST(IRQ_PORT_IDX, nrf24l01_isr);
}



#endif

  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2022-09-09 16:30
    关注
    不知道你这个问题是否已经解决, 如果还没有解决的话:
    • 建议你看下这篇博客👉 :NRF24L01

    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 以帮助更多的人 ^-^
    评论

报告相同问题?

悬赏问题

  • ¥30 STM32 INMP441无法读取数据
  • ¥100 求汇川机器人IRCB300控制器和示教器同版本升级固件文件升级包
  • ¥15 用visualstudio2022创建vue项目后无法启动
  • ¥15 x趋于0时tanx-sinx极限可以拆开算吗
  • ¥500 把面具戴到人脸上,请大家贡献智慧
  • ¥15 任意一个散点图自己下载其js脚本文件并做成独立的案例页面,不要作在线的,要离线状态。
  • ¥15 各位 帮我看看如何写代码,打出来的图形要和如下图呈现的一样,急
  • ¥30 c#打开word开启修订并实时显示批注
  • ¥15 如何解决ldsc的这条报错/index error
  • ¥15 VS2022+WDK驱动开发环境