2401_85308619 2024-12-13 08:38 采纳率: 44.4%
浏览 8
已结题

NRF24L01无法实时接收数据

stm32f103用NRF24L01无法实时接收数据

发送:

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "NRF24L01.h"
#include "My_ADC.h"

int main(void)
{
    uint8_t Buf[32]={0};
    NRF24L01_Init();
    AD_Init();       
    while (1)
    {
        uint8_t Speed= (uint8_t)(AD_Value[1]>>4);
        Speed = AD_Value[1]; 
        Buf[0] = Speed;
        NRF24L01_SendBuf(Buf);
    }
}

接收:

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "Timer.h"
#include "PWM.h"
#include "NRF24L01.h"
#include "OLED.h"


int main(void)
{
    uint8_t Buf[32] = {0};
    uint8_t Mode = 0;
    Timer_Init();        //定时器初始化
    PWM_Init();    
    NRF24L01_Init();
    OLED_Init();
    while (1)
    {
        uint16_t Speed;
        OLED_ShowHexNum(1,1,Buf[0],4);
        Delay_ms(10);
        if (NRF24L01_Get_Value_Flag() == 0)
        {
            NRF24L01_GetRxBuf(Buf);
        }
            Speed = Buf[0]/128;
            PWM_SetCompare1(Speed);
            PWM_SetCompare2(Speed);
            PWM_SetCompare3(Speed);
            PWM_SetCompare4(Speed);
                
    }
}

NRF24L01.c

#include "NRF24L01.h"
#include "NRF24L01_define.h"
#include "stm32f10x.h"                  // Device header
#include "Delay.h"

/***************************************************************************

主要函数使用说明:

NRF24L01_Pin_Init()        引脚初始化, 无参数,无返回值,一般不调用,初始化直接调用NRF24L01_Init()即可

*---------------------------------------------------------------------------*
NRF24L01_Write_Reg(uint8_t Reg, uint8_t Value)        写NRF24L01寄存器

参数:Reg, 寄存器地址
      Value:要写入的数据
返回值:状态值
*---------------------------------------------------------------------------*
NRF24L01_Read_Reg(uint8_t Reg)        读NRF24L01寄存器

参数:Reg:寄存器地址
返回值:状态值
*---------------------------------------------------------------------------*
NRF24L01_Read_Buf(uint8_t Reg, uint8_t *Buf, uint8_t Len)    一次读NRF24L01寄存器多个字节

参数:Reg:寄存器地址;*Buf:寄存器字节读出后存储的数组;Len:要读出的字节个数
返回值:状态值
*---------------------------------------------------------------------------*
NRF24L01_Write_Buf(uint8_t Reg, uint8_t *Buf, uint8_t Len)        一次写NRF24L01寄存器多个字节

参数:Reg:寄存器地址;*Buf:寄存器写入字节的存放数组;Len:要读出的字节个数
返回值:状态值
*---------------------------------------------------------------------------*
NRF24L01_GetRxBuf(uint8_t *Buf)        读出接收到的数据,为多个字节

参数:*Buf多个字节存放的数组
返回值:状态值
*---------------------------------------------------------------------------*
NRF24L01_SendTxBuf(uint8_t *Buf)    发送多个字节

参数:*Buf要发送的字节存放的数组
返回值:状态值
*---------------------------------------------------------------------------*
NRF24L01_Check(void)                检验NRF24L01是否存在

返回值:1:不存在,0:存在
*---------------------------------------------------------------------------*
NRF24L01_Init()                        NRF24L01初始化,包含检验NRF24L01是否存在、收发配置初始化,初始化直接调用该函数即可

*---------------------------------------------------------------------------*
NRF24L01_RT_Init(void)                 NRF24L01收发配置初始化
*---------------------------------------------------------------------------*
NRF24L01_SendBuf(uint8_t *Buf)        NRF24L01发送多个字节数据

参数:要发送字节存放的数组
*---------------------------------------------------------------------------*
uint8_t NRF24L01_Get_Value_Flag()    获取中断标志,一旦接收到数据,返回0

返回值:0:接收到数据;1:未接收到数据

************************************************************/



#define TX_ADR_WIDTH    5     //5字节地址宽度
#define RX_ADR_WIDTH    5     //5字节地址宽度
#define TX_PLOAD_WIDTH  32    //32字节有效数据宽度
#define RX_PLOAD_WIDTH  32    //32字节有效数据宽度

const uint8_t TX_ADDRESS[TX_ADR_WIDTH]={0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; 
const uint8_t RX_ADDRESS[RX_ADR_WIDTH]={0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; 


void W_SS(uint8_t BitValue)
{
    GPIO_WriteBit(CSN_Port, CSN_Pin, (BitAction)BitValue);
} 

void W_CE(uint8_t BitValue)
{
    GPIO_WriteBit(CE_Port, CE_Pin, (BitAction)BitValue);
} 

void W_SCK(uint8_t BitValue)
{
    GPIO_WriteBit(SCK_Port, SCK_Pin, (BitAction)BitValue);
} 

void W_MOSI(uint8_t BitValue)
{
    GPIO_WriteBit(MOSI_Port, MOSI_Pin,(BitAction)BitValue);
} 

uint8_t R_MISO(void)
{
    return GPIO_ReadInputDataBit(MISO_Port, MISO_Pin);
}

uint8_t R_IRQ(void)
{
    return GPIO_ReadInputDataBit(IRQ_Port, IRQ_Pin);
}

void NRF24L01_Pin_Init(void)    
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB,ENABLE);
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin = CSN_Pin;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(CSN_Port, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin = SCK_Pin;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(SCK_Port, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin = MOSI_Pin;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(MOSI_Port, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Pin = CE_Pin;  
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(CE_Port, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Pin = MISO_Pin;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(MISO_Port, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Pin = IRQ_Pin;              
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(IRQ_Port, &GPIO_InitStructure);
    
}
        


uint8_t SPI_SwapByte(uint8_t Byte)  
{
    uint8_t i;
    for(i = 0; i < 8; i ++) 
    {
        if((uint8_t)(Byte & 0x80) == 0x80)
        {
            W_MOSI(1);
        }         
        else 
        {
            W_MOSI(0);
        }            
        Byte = (Byte << 1);            
        W_SCK(1);                    
        Byte |= R_MISO();            
        W_SCK(0);                    
    }
    return Byte;
}
uint8_t NRF24L01_Write_Reg(uint8_t Reg, uint8_t Value)
{
    uint8_t Status;

    W_SS(0);                  
      Status = SPI_SwapByte(Reg);
    SPI_SwapByte(Value);    
    W_SS(1);                 

    return Status;
}

uint8_t NRF24L01_Read_Reg(uint8_t Reg)
{
     uint8_t Value;

    W_SS(0);              
      SPI_SwapByte(Reg);        
    Value = SPI_SwapByte(NOP);
    W_SS(1);                 

    return Value;
}




uint8_t NRF24L01_Read_Buf(uint8_t Reg, uint8_t *Buf, uint8_t Len)
{
    uint8_t Status, i;
    W_SS(0);                        
    Status =SPI_SwapByte(Reg);        
     for(i = 0; i < Len; i ++)
    {
        Buf[i] = SPI_SwapByte(NOP);    
    }
    W_SS(1);                         
    return Status;                    
}

uint8_t NRF24L01_Write_Buf(uint8_t Reg, uint8_t *Buf, uint8_t Len)
{
    uint8_t Status, i;
    W_SS(0); 
    Status = SPI_SwapByte(Reg);        
    for(i = 0; i < Len; i ++)
    {
        SPI_SwapByte(*Buf ++);         
    }
    W_SS(1); 
    return Status;                  
}                                                     

uint8_t NRF24L01_GetRxBuf(uint8_t *Buf)
{
    uint8_t State;
    State = NRF24L01_Read_Reg(STATUS);              
    NRF24L01_Write_Reg(nRF_WRITE_REG + STATUS, State);
    if(State & RX_OK)                                
    {                                                       
        W_CE(1);                                            
        NRF24L01_Read_Buf(RD_RX_PLOAD, Buf, RX_PLOAD_WIDTH);
        NRF24L01_Write_Reg(FLUSH_RX, NOP);                    
        W_CE(1);                
        Delay_us(150);
        return 0; 
    }       
    return 1;
}
uint8_t NRF24L01_SendTxBuf(uint8_t *Buf)
{
    uint8_t State;
   
    W_CE(0);                                                
      NRF24L01_Write_Buf(WR_TX_PLOAD, Buf, TX_PLOAD_WIDTH);    
     W_CE(1);                                                
    while(R_IRQ() == 1);                                    
    State = NRF24L01_Read_Reg(STATUS);                      
    NRF24L01_Write_Reg(nRF_WRITE_REG + STATUS, State);         
    if(State&MAX_TX)                                         
    {
        NRF24L01_Write_Reg(FLUSH_TX, NOP);                    
        return MAX_TX; 
    }
    if(State & TX_OK)    
    {
        return TX_OK;
    }
    return NOP;    
}

uint8_t NRF24L01_Check(void)
{
    uint8_t check_in_buf[5] = {0x11 ,0x22, 0x33, 0x44, 0x55};
    uint8_t check_out_buf[5] = {0x00};

    W_SCK(0);
    W_SS(1);   
    W_CE(0);    

    NRF24L01_Write_Buf(nRF_WRITE_REG + TX_ADDR, check_in_buf, 5);

    NRF24L01_Read_Buf(nRF_READ_REG + TX_ADDR, check_out_buf, 5);

    if((check_out_buf[0] == 0x11) && (check_out_buf[1] == 0x22) && (check_out_buf[2] == 0x33) && (check_out_buf[3] == 0x44) && (check_out_buf[4] == 0x55))
    {
        return 0;
    }
    else 
    {
        return 1;
    }
}            


void NRF24L01_RT_Init(void) 
{    
    W_CE(0);          
      NRF24L01_Write_Reg(nRF_WRITE_REG+RX_PW_P0, RX_PLOAD_WIDTH);
    NRF24L01_Write_Reg(FLUSH_RX, NOP);                                    
      NRF24L01_Write_Buf(nRF_WRITE_REG + TX_ADDR, (uint8_t*)TX_ADDRESS, TX_ADR_WIDTH);
      NRF24L01_Write_Buf(nRF_WRITE_REG + RX_ADDR_P0, (uint8_t*)RX_ADDRESS, RX_ADR_WIDTH);   
      NRF24L01_Write_Reg(nRF_WRITE_REG + EN_AA, 0x01);     
      NRF24L01_Write_Reg(nRF_WRITE_REG + EN_RXADDR, 0x01); 
      NRF24L01_Write_Reg(nRF_WRITE_REG + SETUP_RETR, 0x1A);
      NRF24L01_Write_Reg(nRF_WRITE_REG + RF_CH, 0);        
      NRF24L01_Write_Reg(nRF_WRITE_REG + RF_SETUP, 0x0F);  
      NRF24L01_Write_Reg(nRF_WRITE_REG + CONFIG, 0x0F);    
    W_CE(1);                                      
}

void NRF24L01_Init()
{
    NRF24L01_Pin_Init();
    while(NRF24L01_Check());
    NRF24L01_RT_Init();
    
}

void NRF24L01_SendBuf(uint8_t *Buf)
{
    W_CE(0);                                    
    NRF24L01_Write_Reg(nRF_WRITE_REG + CONFIG, 0x0E);   
    W_CE(1);
    Delay_us(15);
    NRF24L01_SendTxBuf(Buf);                        
    W_CE(0);
    NRF24L01_Write_Reg(nRF_WRITE_REG + CONFIG, 0x0F);
    W_CE(1);    
}

uint8_t NRF24L01_Get_Value_Flag()
{
    return R_IRQ();
}

NRF24L01.h

#ifndef __NRF24L01_H
#define __NRF24L01_H

#include "stm32f10x.h"                  // Device header

uint8_t SPI_SwapByte(uint8_t byte);
uint8_t NRF24L01_Write_Reg(uint8_t reg,uint8_t value);
uint8_t NRF24L01_Read_Reg(uint8_t reg);
uint8_t NRF24L01_Read_Buf(uint8_t reg,uint8_t *pBuf, uint8_t len);
uint8_t NRF24L01_Write_Buf(uint8_t reg, uint8_t *pBuf, uint8_t len);
uint8_t NRF24L01_GetRxBuf(uint8_t *rxbuf);
uint8_t NRF24L01_SendTxBuf(uint8_t *txbuf);
uint8_t NRF24L01_Check(void);
void NRF24L01_RT_Init(void);
void NRF24L01_Init(void);
void NRF24L01_SendBuf(uint8_t *Buf);
void NRF24L01_Pin_Init(void);
uint8_t NRF24L01_Get_Value_Flag();

#endif

NRF24L01_define.h

#ifndef __nRF24L01_H
#define __nRF24L01_H

/**********  NRF24L01引脚定义  ***********/
#define IRQ_Port   GPIOA
#define CE_Port    GPIOA
#define MISO_Port  GPIOA
#define MOSI_Port  GPIOA
#define SCK_Port   GPIOA
#define CSN_Port   GPIOA

#define IRQ_Pin    GPIO_Pin_11
#define CE_Pin     GPIO_Pin_15
#define MOSI_Pin   GPIO_Pin_7
#define MISO_Pin   GPIO_Pin_6
#define SCK_Pin    GPIO_Pin_5
#define CSN_Pin    GPIO_Pin_4

/**********  NRF24L01寄存器操作命令  ***********/
#define nRF_READ_REG        0x00 
#define nRF_WRITE_REG       0x20 
#define RD_RX_PLOAD     0x61  
#define WR_TX_PLOAD     0xA0  
#define FLUSH_TX        0xE1  
#define FLUSH_RX        0xE2  
#define REUSE_TX_PL     0xE3  
#define NOP             0xFF  
/**********  NRF24L01寄存器地址   *************/
#define CONFIG          0x00                           
#define EN_AA           0x01  
#define EN_RXADDR       0x02  
#define SETUP_AW        0x03  
#define SETUP_RETR      0x04  
#define RF_CH           0x05  
#define RF_SETUP        0x06  
#define STATUS          0x07  
#define OBSERVE_TX      0x08  
#define CD              0x09  
#define RX_ADDR_P0      0x0A  
#define RX_ADDR_P1      0x0B  
#define RX_ADDR_P2      0x0C  
#define RX_ADDR_P3      0x0D  
#define RX_ADDR_P4      0x0E  
#define RX_ADDR_P5      0x0F  
#define TX_ADDR         0x10  
#define RX_PW_P0        0x11   
#define RX_PW_P1        0x12   
#define RX_PW_P2        0x13   
#define RX_PW_P3        0x14   
#define RX_PW_P4        0x15  
#define RX_PW_P5        0x16  
#define FIFO_STATUS     0x17  

/******   STATUS寄存器bit位定义      *******/
#define MAX_TX      0x10        //达到最大发送次数中断
#define TX_OK       0x20        //TX发送完成中断
#define RX_OK       0x40        //接收到数据中断

#endif

ADC.c

#include "stm32f10x.h"                  // Device header

uint32_t AD_Value[4];                    //定义用于存放AD转换结果的全局数组

/**
  * 函    数:AD初始化
  * 参    数:无
  * 返 回 值:无
  */
void AD_Init(void)
{
    /*开启时钟*/
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);    //开启ADC1的时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);    //开启GPIOA的时钟
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);        //开启DMA1的时钟
    
    /*设置ADC时钟*/
    RCC_ADCCLKConfig(RCC_PCLK2_Div6);                        //选择时钟6分频,ADCCLK = 72MHz / 6 = 12MHz
    
    /*GPIO初始化*/
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);                    //将PA0、PA1、PA2和PA3引脚初始化为模拟输入
    
    /*规则组通道配置*/
    ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);    //规则组序列1的位置,配置为通道0
    ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_55Cycles5);    //规则组序列2的位置,配置为通道1
    ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_55Cycles5);    //规则组序列3的位置,配置为通道2
    ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_55Cycles5);    //规则组序列4的位置,配置为通道3
    
    /*ADC初始化*/
    ADC_InitTypeDef ADC_InitStructure;                                            //定义结构体变量
    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;                            //模式,选择独立模式,即单独使用ADC1
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;                        //数据对齐,选择右对齐
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;            //外部触发,使用软件触发,不需要外部触发
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;                            //连续转换,使能,每转换一次规则组序列后立刻开始下一次转换
    ADC_InitStructure.ADC_ScanConvMode = ENABLE;                                //扫描模式,使能,扫描规则组的序列,扫描数量由ADC_NbrOfChannel确定
    ADC_InitStructure.ADC_NbrOfChannel = 4;                                        //通道数,为4,扫描规则组的前4个通道
    ADC_Init(ADC1, &ADC_InitStructure);                                            //将结构体变量交给ADC_Init,配置ADC1
    
    /*DMA初始化*/
    DMA_InitTypeDef DMA_InitStructure;                                            //定义结构体变量
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;                //外设基地址,给定形参AddrA
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;    //外设数据宽度,选择半字,对应16为的ADC数据寄存器
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;            //外设地址自增,选择失能,始终以ADC数据寄存器为源
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)AD_Value;                    //存储器基地址,给定存放AD转换结果的全局数组AD_Value
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;            //存储器数据宽度,选择半字,与源数据宽度对应
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                        //存储器地址自增,选择使能,每次转运后,数组移到下一个位置
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;                            //数据传输方向,选择由外设到存储器,ADC数据寄存器转到数组
    DMA_InitStructure.DMA_BufferSize = 4;                                        //转运的数据大小(转运次数),与ADC通道数一致
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                                //模式,选择循环模式,与ADC的连续转换一致
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                                //存储器到存储器,选择失能,数据由ADC外设触发转运到存储器
    DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;                        //优先级,选择中等
    DMA_Init(DMA1_Channel1, &DMA_InitStructure);                                //将结构体变量交给DMA_Init,配置DMA1的通道1
    
    /*DMA和ADC使能*/
    DMA_Cmd(DMA1_Channel1, ENABLE);                            //DMA1的通道1使能
    ADC_DMACmd(ADC1, ENABLE);                                //ADC1触发DMA1的信号使能
    ADC_Cmd(ADC1, ENABLE);                                    //ADC1使能
    
    /*ADC校准*/
    ADC_ResetCalibration(ADC1);                                //固定流程,内部有电路会自动执行校准
    while (ADC_GetResetCalibrationStatus(ADC1) == SET);
    ADC_StartCalibration(ADC1);
    while (ADC_GetCalibrationStatus(ADC1) == SET);
    
    /*ADC触发*/
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);    //软件触发ADC开始工作,由于ADC处于连续转换模式,故触发一次后ADC就可以一直连续不断地工作
}

ADC.h

#ifndef __AD_H
#define __AD_H

extern uint32_t AD_Value[4];

void AD_Init(void);

#endif
  • 写回答

1条回答 默认 最新

  • 道友老李 JWE233286一种基于机器视觉的水表指针读数识别及修正的方法 专利发明者 2024-12-13 09:08
    关注
    让道友老李来帮你解答,本回答参考通义千问qwen-plus编写提供,如果还有疑问可以评论或留言
    ### 问题分析

    从你提供的代码来看,STM32F103使用NRF24L01模块无法实时接收数据的问题可能涉及以下几个方面:

    1. SPI通信问题:确保SPI通信正常,引脚配置正确。
    2. NRF24L01配置问题:确保NRF24L01的配置正确,包括地址、通道、数据率等。
    3. 中断处理问题:确保中断处理及时,避免数据丢失。
    4. 发送和接收逻辑问题:确保发送和接收逻辑正确,避免数据发送和接收不同步。

    详细分析和解决方案

    1. SPI通信问题

    确保SPI通信正常,引脚配置正确。你可以通过简单的SPI读写测试来验证SPI通信是否正常。

    // 在NRF24L01_Init()中添加SPI测试
    void NRF24L01_Init() {
        NRF24L01_Pin_Init();
        while (NRF24L01_Check());
    
        // 测试SPI通信
        W_SS(0);
        uint8_t test_value = 0xAA;
        uint8_t read_value = SPI_SwapByte(test_value);
        W_SS(1);
    
        if (read_value != 0xAA) {
            // SPI通信异常,需要检查引脚配置和硬件连接
            while (1);
        }
    
        NRF24L01_RT_Init();
    }
    

    2. NRF24L01配置问题

    确保NRF24L01的配置正确,包括地址、通道、数据率等。你可以在NRF24L01_RT_Init()中添加更多的调试信息,确保配置正确。

    void NRF24L01_RT_Init(void) {
        W_CE(0);
    
        // 设置接收数据长度
        NRF24L01_Write_Reg(nRF_WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH);
    
        // 清空接收缓冲区
        NRF24L01_Write_Reg(FLUSH_RX, NOP);
    
        // 设置发射地址
        NRF24L01_Write_Buf(nRF_WRITE_REG + TX_ADDR, (uint8_t*)TX_ADDRESS, TX_ADR_WIDTH);
    
        // 设置接收地址
        NRF24L01_Write_Buf(nRF_WRITE_REG + RX_ADDR_P0, (uint8_t*)RX_ADDRESS, RX_ADR_WIDTH);
    
        // 启动自动应答
        NRF24L01_Write_Reg(nRF_WRITE_REG + EN_AA, 0x01);
    
        // 启用接收地址
        NRF24L01_Write_Reg(nRF_WRITE_REG + EN_RXADDR, 0x01);
    
        // 设置重发次数和延迟
        NRF24L01_Write_Reg(nRF_WRITE_REG + SETUP_RETR, 0x1A);
    
        // 设置通信频道
        NRF24L01_Write_Reg(nRF_WRITE_REG + RF_CH, 0);
    
        // 设置通信速率和功率
        NRF24L01_Write_Reg(nRF_WRITE_REG + RF_SETUP, 0x0F);
    
        // 设置配置寄存器
        NRF24L01_Write_Reg(nRF_WRITE_REG + CONFIG, 0x0F);
    
        // 使能CE引脚
        W_CE(1);
    }
    

    3. 中断处理问题

    确保中断处理及时,避免数据丢失。你可以在NRF24L01_GetRxBuf()中添加更多的调试信息,确保中断处理正常。

    uint8_t NRF24L01_GetRxBuf(uint8_t *Buf) {
        uint8_t State;
        State = NRF24L01_Read_Reg(STATUS);
    
        NRF24L01_Write_Reg(nRF_WRITE_REG + STATUS, State);
    
        if (State & RX_OK) {
            W_CE(1);
            NRF24L01_Read_Buf(RD_RX_PLOAD, Buf, RX_PLOAD_WIDTH);
            NRF24L01_Write_Reg(FLUSH_RX, NOP);
            W_CE(1);
            Delay_us(150);
            return 0;
        }
        return 1;
    }
    

    4. 发送和接收逻辑问题

    确保发送和接收逻辑正确,避免数据发送和接收不同步。你可以在主循环中添加更多的调试信息,确保发送和接收逻辑正确。

    // 发送端
    int main(void) {
        uint8_t Buf[32] = {0};
        NRF24L01_Init();
        AD_Init();
    
        while (1) {
            uint8_t Speed = (uint8_t)(AD_Value[1] >> 4);
            Buf[0] = Speed;
            NRF24L01_SendBuf(Buf);
            Delay_ms(100); // 增加延时,避免发送过快
        }
    }
    
    // 接收端
    int main(void) {
        uint8_t Buf[32] = {0};
        uint8_t Mode = 0;
        Timer_Init();        // 定时器初始化
        PWM_Init();
        NRF24L01_Init();
        OLED_Init();
    
        while (1) {
            if (NRF24L01_Get_Value_Flag() == 0) {
                NRF24L01_GetRxBuf(Buf);
                uint16_t Speed = Buf[0] / 128;
                PWM_SetCompare1(Speed);
                PWM_SetCompare2(Speed);
                PWM_SetCompare3(Speed);
                PWM_SetCompare4(Speed);
                OLED_ShowHexNum(1, 1, Buf[0], 4);
            }
            Delay_ms(10); // 增加延时,避免处理过快
        }
    }
    

    总结

    通过以上步骤,你可以逐步排查和解决STM32F103使用NRF24L01模块无法实时接收数据的问题。确保SPI通信正常,NRF24L01配置正确,中断处理及时,发送和接收逻辑正确。希望这些方法能帮助你解决问题。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 12月21日
  • 已采纳回答 12月13日
  • 创建了问题 12月13日