代码

1. 不使用中断处理IRQ

/*
 * nrf24l01.c
 *
 *  Created on: May 4, 2022
 *      Author: zhangrun
 */

#include "nrf24l01.h"

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

/**
 * @brief  初始化NRF24l01
 * @retval none
 */
void nrf_init(void)
{
    NRF24L01_CE_LOW;          //使能24L01
    NRF24L01_SPI_CSN_DISABLE; // SPI片选取消
}

/**
 * @brief  SPI发送一字节数据并接收一字节数据
 * @param  send_byte 待发送的数据
 * @retval 接收到的数据
 */
uint8_t read_write_byte(uint8_t send_byte)
{
    uint8_t read_byte;
    if (HAL_SPI_TransmitReceive(&hspi1, &send_byte, &read_byte, sizeof(uint8_t), 0xFF) != HAL_OK)
    {
        read_byte = 0xFF;
    }

    return read_byte;
}

/**
 * @brief  检测nrf24l01是否存在
 * @retval 0 检测到;1 未检测到
 */
uint8_t nrf_check(void)
{
    uint8_t buf[5] = {0XA5, 0XA5, 0XA5, 0XA5, 0XA5};
    uint8_t i;

    nrf_write_buf(NRF_WRITE_REG + TX_ADDR, buf, 5); //写入5个字节的地址.
    nrf_read_buf(TX_ADDR, buf, 5);                  //读出写入的地址
    for (i = 0; i < 5; i++)
    {
        if (buf[i] != 0XA5)
        {
            break;
        }
    }
    if (i != 5)
    {
        return 1; //检测24L01错误
    }

    return 0; //检测到24L01
}

/**
 * @brief  SPI写寄存器
 * @param  reg 寄存器地址
 * @param  value 要写入的值
 * @retval 返回状态寄存器值
 */
uint8_t nrf_write_reg(uint8_t reg, uint8_t value)
{
    uint8_t status;
    NRF24L01_SPI_CSN_ENABLE;       //使能SPI传输
    status = read_write_byte(reg); //发送寄存器号
    read_write_byte(value);        //写入寄存器的值
    NRF24L01_SPI_CSN_DISABLE;      //关闭SPI传输

    return status; //返回状态寄存器值
}

/**
 * @brief  SPI读寄存器
 * @param  reg 寄存器地址
 * @retval 返回读寄存器值
 */
uint8_t nrf_read_reg(uint8_t reg)
{
    uint8_t reg_val;
    NRF24L01_SPI_CSN_ENABLE;         //使能SPI传输
    read_write_byte(reg);            //发送寄存器号
    reg_val = read_write_byte(0XFF); //读取寄存器内容
    NRF24L01_SPI_CSN_DISABLE;        //禁止SPI传输
    return reg_val;                  //返回状态值
}

/**
 * @brief  SPI读寄存器区域
 * @param  reg 寄存器地址
 * @param  *buf 读取回的值放入指针指向的buf
 * @param  len 读取的长度
 * @retval 返回状态寄存器值
 */
uint8_t nrf_read_buf(uint8_t reg, uint8_t *buf, uint8_t len)
{
    uint8_t status;
    uint8_t num;
    NRF24L01_SPI_CSN_ENABLE;                      //使能SPI传输
    status = read_write_byte(NRF_READ_REG + reg); //发送寄存器值(位置),并读取状态值
    for (num = 0; num < len; num++)
    {
        buf[num] = read_write_byte(0XFF); //读出数据
    }
    NRF24L01_SPI_CSN_DISABLE; //关闭SPI传输

    return status; //返回状态寄存器值
}

/**
 * @brief  SPI写寄存器区域
 * @param  reg 寄存器地址
 * @param  *buf 将指针指向的buf写入reg寄存器
 * @param  len 读取的长度
 * @retval 返回状态寄存器值
 */
uint8_t nrf_write_buf(uint8_t reg, uint8_t *buf, uint8_t len)
{
    uint8_t status;
    uint8_t num;
    NRF24L01_SPI_CSN_ENABLE;       //使能SPI传输
    status = read_write_byte(reg); //发送寄存器值(位置),并读取状态值
    for (num = 0; num < len; num++)
    {
        read_write_byte(*buf++); //写入数据
    }
    NRF24L01_SPI_CSN_DISABLE; //关闭SPI传输

    return status; //返回读到的状态值
}

/**
 * @brief  发送数据
 * @param  *buf 待发送的buf
 * @retval 返回状态值
 */
uint8_t nrf_send_pkg(uint8_t *buf)
{
    uint8_t status;
    NRF24L01_CE_LOW;
    nrf_write_buf(WR_TX_PLOAD, buf, TX_PLOAD_WIDTH); //写数据到TX BUF  32个字节
    NRF24L01_CE_HIGH;                                  //启动发送

    while (NRF24L01_IRQ_PIN_READ != 0)
        ; //等待发送完成

    status = nrf_read_reg(STATUS);                 //读取状态寄存器的值
    nrf_write_reg(NRF_WRITE_REG + STATUS, status); //清除TX_DS或MAX_RT中断标志
    if (status & MAX_TX)                           //达到最大重发次数
    {
        nrf_write_reg(FLUSH_TX, 0xff); //清除TX FIFO寄存器
        return MAX_TX;
    }
    if (status & TX_OK) //发送完成
    {
        return TX_OK;
    }
    return 0xff; //其他原因发送失败
}

/**
 * @brief  接收数据
 * @param  *buf 接收的buf
 * @retval 返回状态值
 */
uint8_t nrf_receive_pkg(uint8_t *buf)
{
    uint8_t status;
    status = nrf_read_reg(STATUS);                 //读取状态寄存器的值
    nrf_write_reg(NRF_WRITE_REG + STATUS, status); //清除TX_DS或MAX_RT中断标志
    if (status & RX_OK)                            //接收到数据
    {
        nrf_read_buf(RD_RX_PLOAD, buf, RX_PLOAD_WIDTH); //读取数据
        nrf_write_reg(FLUSH_RX, 0xff);                    //清除RX FIFO寄存器
        return 0;
    }

    return 1; //没收到任何数据
}

/**
 * @brief  接收模式
 * @retval none
 */
void nrf_rx_mode(void)
{
    NRF24L01_CE_LOW;
    nrf_write_buf(NRF_WRITE_REG + RX_ADDR_P0, (uint8_t *)RX_ADDRESS, RX_ADR_WIDTH);
    nrf_write_reg(NRF_WRITE_REG + EN_AA, 0x01);
    nrf_write_reg(NRF_WRITE_REG + EN_RXADDR, 0x01);
    nrf_write_reg(NRF_WRITE_REG + RF_CH, 40);
    nrf_write_reg(NRF_WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH);
    nrf_write_reg(NRF_WRITE_REG + RF_SETUP, 0x07);
    nrf_write_reg(NRF_WRITE_REG + CONFIG, 0x0F);
    NRF24L01_CE_HIGH;
    HAL_Delay(1);
}

/**
 * @brief  发送模式
 * @retval none
 */
void nrf_tx_mode(void)
{

    NRF24L01_CE_LOW;
    nrf_write_buf(NRF_WRITE_REG + TX_ADDR, (uint8_t *)TX_ADDRESS, TX_ADR_WIDTH);
    nrf_write_buf(NRF_WRITE_REG + RX_ADDR_P0, (uint8_t *)RX_ADDRESS, RX_ADR_WIDTH);
    nrf_write_reg(NRF_WRITE_REG + EN_AA, 0x01);
    nrf_write_reg(NRF_WRITE_REG + EN_RXADDR, 0x01);
    nrf_write_reg(NRF_WRITE_REG + SETUP_RETR, 0x1a);
    nrf_write_reg(NRF_WRITE_REG + RF_CH, 40);
    nrf_write_reg(NRF_WRITE_REG + RF_SETUP, 0x07);
    nrf_write_reg(NRF_WRITE_REG + CONFIG, 0x0e);
    NRF24L01_CE_HIGH;
    HAL_Delay(1);
}

/**
 * @brief  掉电模式
 * @retval none
 */
void nrf_low_power_mode(void)
{
    NRF24L01_CE_LOW;
    nrf_write_reg(NRF_WRITE_REG + CONFIG, 0x00);
}

2. 使用中断处理

/*
 * nrf24l01.h
 *
 *  Created on: May 4, 2022
 *      Author: zhangrun
 */

#ifndef NRF24L01_H_
#define NRF24L01_H_

#include "main.h"
#include "spi.h"
#include "gpio.h"
#include "usbd_cdc_if.h"

//命令代码
#define NRF_READ_REG    0x00//读命令
#define NRF_WRITE_REG   0x20//写命令
#define RD_RX_PLOAD     0x61//读RX有效数据
#define WR_TX_PLOAD     0xA0//写TX有效数据
#define FLUSH_TX        0xE1//清除TX FIFO寄存器
#define FLUSH_RX        0xE2//清除RX FIFO寄存器
#define REUSE_TX_PL     0xE3//重新使用上一包发射的有效数据
#define NOP             0xFF//空操作

//寄存器地址
#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

//24L01发送接收数据宽度定义
#define TX_ADR_WIDTH    5//5字节的地址宽度
#define RX_ADR_WIDTH    5//5字节的地址宽度
#define TX_PLOAD_WIDTH  32//32字节的用户数据宽度
#define RX_PLOAD_WIDTH  32//32字节的用户数据宽度

//CE引脚控制
#define NRF24L01_CE_HIGH HAL_GPIO_WritePin(SPI_CE_GPIO_Port, SPI_CE_Pin, GPIO_PIN_SET)
#define NRF24L01_CE_LOW  HAL_GPIO_WritePin(SPI_CE_GPIO_Port, SPI_CE_Pin, GPIO_PIN_RESET)
//CSN引脚
#define NRF24L01_SPI_CSN_DISABLE HAL_GPIO_WritePin(SPI_CSN_GPIO_Port, SPI_CSN_Pin, GPIO_PIN_SET)
#define NRF24L01_SPI_CSN_ENABLE  HAL_GPIO_WritePin(SPI_CSN_GPIO_Port, SPI_CSN_Pin, GPIO_PIN_RESET)
//IRQ引脚
#define NRF24L01_IRQ_PIN_READ    HAL_GPIO_ReadPin(SPI_IRQ_GPIO_Port, SPI_IRQ_Pin)

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

void nrf_init(void);
uint8_t read_write_byte(uint8_t send_byte);
uint8_t nrf_check(void);
uint8_t nrf_write_reg(uint8_t reg,uint8_t value);
uint8_t nrf_read_reg(uint8_t reg);
uint8_t nrf_read_buf(uint8_t reg, uint8_t *buf, uint8_t len);
uint8_t nrf_write_buf(uint8_t reg, uint8_t *buf, uint8_t len);
uint8_t nrf_send_pkg(uint8_t *buf);
uint8_t nrf_receive_pkg(uint8_t *buf);
void nrf_rx_mode(void);
void nrf_tx_mode(void);
void nrf_low_power_mode(void);

#endif /* NRF24L01_H_ */

3.发送

uint8_t test_buf[32] = "Hello!";
nrf_init();
while(nrf_check() != 0)
{
    usb_debug("no link\n");
    HAL_Delay(1000);
}
nrf_tx_mode();
while (1)
{
	nrf_send_pkg(test_buf);
}

4.接收

int main(void)
{
uint8_t test_buf[33];
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_SPI1_Init();
MX_USB_DEVICE_Init();
NRF24L01_Init();
while(nrf_check() != 0)
{
    usb_debug("no link\n");
    HAL_Delay(1000);
}
nrf_rx_mode();
while (1)
{
	if(nrf_rx_pkg(test_buf) == 0)
	{
		 test_buf[33]=0;//加入字符串结束符
	     usb_debug("%s",test_buf);
	}
}
}