项目场景:
使用stm32进行nrf24l01发送和接收数据(本人使用的是淘宝上购买的si24)
问题描述
在确认NRF24L01硬件方面没有任何问题后(包括没有任何复用的引脚等),可能会出现2种问题
1、NRF24L01发送数据正常但却无法接收数据
2、NRF24L01发送数据正常但只能在系统复位后接收一次数据
用于向NRF特定的寄存器写入和读出数据代码如下:
/**
* @brief 用于向NRF特定的寄存器写入数据
* @param
* @arg reg:NRF的命令+寄存器地址
* @arg dat:将要向寄存器写入的数据
* @retval NRF的status寄存器的状态
*/
u8 SPI_NRF_WriteReg(u8 reg,u8 dat)
{
u8 status;
NRF_CE_LOW();
/*置低CSN,使能SPI传输*/
NRF_CSN_LOW();
/*发送命令及寄存器号 */
status = SPI_NRF_RW(reg);
/*向寄存器写入数据*/
SPI_NRF_RW(dat);
/*CSN拉高,完成*/
NRF_CSN_HIGH();
/*返回状态寄存器的值*/
return(status);
}
/**
* @brief 用于从NRF特定的寄存器读出数据
* @param
* @arg reg:NRF的命令+寄存器地址
* @retval 寄存器中的数据
*/
u8 SPI_NRF_ReadReg(u8 reg)
{
u8 reg_val;
NRF_CE_LOW();
/*置低CSN,使能SPI传输*/
NRF_CSN_LOW();
/*发送寄存器号*/
SPI_NRF_RW(reg);
/*读取寄存器的值 */
reg_val = SPI_NRF_RW(NOP);
/*CSN拉高,完成*/
NRF_CSN_HIGH();
return reg_val;
}
/**
* @brief 用于向NRF的寄存器中写入一串数据
* @param
* @arg reg : NRF的命令+寄存器地址
* @arg pBuf:用于存储将被读出的寄存器数据的数组,外部定义
* @arg bytes: pBuf的数据长度
* @retval NRF的status寄存器的状态
*/
u8 SPI_NRF_ReadBuf(u8 reg,u8 *pBuf,u8 bytes)
{
u8 status, byte_cnt;
NRF_CE_LOW();
/*置低CSN,使能SPI传输*/
NRF_CSN_LOW();
/*发送寄存器号*/
status = SPI_NRF_RW(reg);
/*读取缓冲区数据*/
for(byte_cnt=0; byte_cnt < bytes; byte_cnt++)
pBuf[byte_cnt] = SPI_NRF_RW(NOP); //从NRF24L01读取数据
/*CSN拉高,完成*/
NRF_CSN_HIGH();
return status; //返回寄存器状态值
}
/**
* @brief 用于向NRF的寄存器中写入一串数据
* @param
* @arg reg : NRF的命令+寄存器地址
* @arg pBuf:存储了将要写入写寄存器数据的数组,外部定义
* @arg bytes: pBuf的数据长度
* @retval NRF的status寄存器的状态
*/
u8 SPI_NRF_WriteBuf(u8 reg ,u8 *pBuf,u8 bytes)
{
u8 status,byte_cnt;
NRF_CE_LOW();
/*置低CSN,使能SPI传输*/
NRF_CSN_LOW();
/*发送寄存器号*/
status = SPI_NRF_RW(reg);
/*向缓冲区写入数据*/
for(byte_cnt = 0; byte_cnt < bytes; byte_cnt++)
SPI_NRF_RW(*pBuf++); //写数据到缓冲区
/*CSN拉高,完成*/
NRF_CSN_HIGH();
return (status); //返回NRF24L01的状态
}
原因分析:
经过仔细的排查和检查,最后发现问题就出在上面所贴出的四个函数中,如果直接使用上面四个函数的话,就会出现发送数据正常但是却无法接受数据的问题。
下面将SPI_NRF_WriteReg()和SPI_NRF_ReadReg()函数修改如下:
/**
* @brief 用于向NRF特定的寄存器写入数据
* @param
* @arg reg:NRF的命令+寄存器地址
* @arg dat:将要向寄存器写入的数据
* @retval NRF的status寄存器的状态
*/
u8 SPI_NRF_WriteReg(u8 reg,u8 dat)
{
u8 status;
/*置低CSN,使能SPI传输*/
NRF_CSN_LOW();
/*发送命令及寄存器号 */
status = SPI_NRF_RW(reg);
/*向寄存器写入数据*/
SPI_NRF_RW(dat);
/*CSN拉高,完成*/
NRF_CSN_HIGH();
/*返回状态寄存器的值*/
return(status);
}
/**
* @brief 用于从NRF特定的寄存器读出数据
* @param
* @arg reg:NRF的命令+寄存器地址
* @retval 寄存器中的数据
*/
u8 SPI_NRF_ReadReg(u8 reg)
{
u8 reg_val;
/*置低CSN,使能SPI传输*/
NRF_CSN_LOW();
/*发送寄存器号*/
SPI_NRF_RW(reg);
/*读取寄存器的值 */
reg_val = SPI_NRF_RW(NOP);
/*CSN拉高,完成*/
NRF_CSN_HIGH();
return reg_val;
}
对上面的两个函数中的修改仅仅去掉了NRF_CE_LOW();
这时发送数据正常但只能在设备复位后接收一次数据
再次修改代码如下:
/**
* @brief 用于向NRF的寄存器中写入一串数据
* @param
* @arg reg : NRF的命令+寄存器地址
* @arg pBuf:用于存储将被读出的寄存器数据的数组,外部定义
* @arg bytes: pBuf的数据长度
* @retval NRF的status寄存器的状态
*/
u8 SPI_NRF_ReadBuf(u8 reg,u8 *pBuf,u8 bytes)
{
u8 status, byte_cnt;
/*置低CSN,使能SPI传输*/
NRF_CSN_LOW();
/*发送寄存器号*/
status = SPI_NRF_RW(reg);
/*读取缓冲区数据*/
for(byte_cnt=0; byte_cnt < bytes; byte_cnt++)
pBuf[byte_cnt] = SPI_NRF_RW(NOP); //从NRF24L01读取数据
/*CSN拉高,完成*/
NRF_CSN_HIGH();
return status; //返回寄存器状态值
}
/**
* @brief 用于向NRF的寄存器中写入一串数据
* @param
* @arg reg : NRF的命令+寄存器地址
* @arg pBuf:存储了将要写入写寄存器数据的数组,外部定义
* @arg bytes: pBuf的数据长度
* @retval NRF的status寄存器的状态
*/
u8 SPI_NRF_WriteBuf(u8 reg ,u8 *pBuf,u8 bytes)
{
u8 status,byte_cnt;
/*置低CSN,使能SPI传输*/
NRF_CSN_LOW();
/*发送寄存器号*/
status = SPI_NRF_RW(reg);
/*向缓冲区写入数据*/
for(byte_cnt = 0; byte_cnt < bytes; byte_cnt++)
SPI_NRF_RW(*pBuf++); //写数据到缓冲区
/*CSN拉高,完成*/
NRF_CSN_HIGH();
return (status); //返回NRF24L01的状态
}
这次去掉了SPI_NRF_ReadBuf(u8 reg,u8 *pBuf,u8 bytes)和SPI_NRF_WriteBuf(u8 reg ,u8 *pBuf,u8 bytes)函数中的NRF_CE_LOW()
再次测试,数据发送和接受都正常
解决方案:
经过本人测试能用的完整代码如下:
NRF24L01.h
#ifndef __NRF24L01_H
#define __NRF24L01_H
#include "stm32f10x.h"
#define TX_ADR_WIDTH 5 //发射地址宽度
#define TX_PLOAD_WIDTH 32 //发射数据通道有效数据宽度0~32Byte
#define RX_ADR_WIDTH 5
#define RX_PLOAD_WIDTH 32
#define CHANAL 0 //频道选择40
// SPI(nRF24L01) commands , NRF的SPI命令宏定义,详见NRF功能使用文档
#define NRF_READ_REG 0x00 // Define read command to register
#define NRF_WRITE_REG 0x20 // Define write command to register
#define RD_RX_PLOAD 0x61 // Define RX payload register address
#define WR_TX_PLOAD 0xA0 // Define TX payload register address
#define FLUSH_TX 0xE1 // Define flush TX register command
#define FLUSH_RX 0xE2 // Define flush RX register command
#define REUSE_TX_PL 0xE3 // Define reuse TX payload register command
#define NOP 0xFF // Define No Operation, might be used to read status register
// SPI(nRF24L01) registers(addresses) ,NRF24L01 相关寄存器地址的宏定义
#define CONFIG 0x00 // 'Config' register address
#define EN_AA 0x01 // 'Enable Auto Acknowledgment' register address
#define EN_RXADDR 0x02 // 'Enabled RX addresses' register address
#define SETUP_AW 0x03 // 'Setup address width' register address
#define SETUP_RETR 0x04 // 'Setup Auto. Retrans' register address
#define RF_CH 0x05 // 'RF channel' register address
#define RF_SETUP 0x06 // 'RF setup' register address
#define STATUS 0x07 // 'Status' register address
#define OBSERVE_TX 0x08 // 'Observe TX' register address
#define CD 0x09 // 'Carrier Detect' register address
#define RX_ADDR_P0 0x0A // 'RX address pipe0' register address
#define RX_ADDR_P1 0x0B // 'RX address pipe1' register address
#define RX_ADDR_P2 0x0C // 'RX address pipe2' register address
#define RX_ADDR_P3 0x0D // 'RX address pipe3' register address
#define RX_ADDR_P4 0x0E // 'RX address pipe4' register address
#define RX_ADDR_P5 0x0F // 'RX address pipe5' register address
#define TX_ADDR 0x10 // 'TX address' register address
#define RX_PW_P0 0x11 // 'RX payload width, pipe0' register address
#define RX_PW_P1 0x12 // 'RX payload width, pipe1' register address
#define RX_PW_P2 0x13 // 'RX payload width, pipe2' register address
#define RX_PW_P3 0x14 // 'RX payload width, pipe3' register address
#define RX_PW_P4 0x15 // 'RX payload width, pipe4' register address
#define RX_PW_P5 0x16 // 'RX payload width, pipe5' register address
#define FIFO_STATUS 0x17 // 'FIFO Status Register' register address
#define MAX_RT 0x10 //达到最大重发次数中断标志位
#define TX_DS 0x20 //发送完成中断标志位 //
#define RX_DR 0x40 //接收到数据中断标志位
/* NRF1 管脚 */
#define NRF_CSN_GPIO_PORT GPIOC
#define NRF_CSN_PIN GPIO_Pin_6
#define NRF_CSN_GPIO_CLK RCC_APB2Periph_GPIOC
#define NRF_CE_GPIO_PORT GPIOC
#define NRF_CE_PIN GPIO_Pin_5
#define NRF_CE_GPIO_CLK RCC_APB2Periph_GPIOC
#define NRF_IRQ_GPIO_PORT GPIOC
#define NRF_IRQ_PIN GPIO_Pin_4
#define NRF_IRQ_GPIO_CLK RCC_APB2Periph_GPIOC
#define NRF_CSN_HIGH() GPIO_SetBits(NRF_CSN_GPIO_PORT, NRF_CSN_PIN)
#define NRF_CSN_LOW() GPIO_ResetBits(NRF_CSN_GPIO_PORT, NRF_CSN_PIN) //csn置低
#define NRF_CE_HIGH() GPIO_SetBits(NRF_CE_GPIO_PORT,NRF_CE_PIN)
#define NRF_CE_LOW() GPIO_ResetBits(NRF_CE_GPIO_PORT,NRF_CE_PIN) //CE置低
#define NRF_Read_IRQ() GPIO_ReadInputDataBit(NRF_IRQ_GPIO_PORT, NRF_IRQ_PIN) //中断引脚
extern u8 RX_BUF[RX_PLOAD_WIDTH]; //接收数据缓存
extern u8 TX_BUF[TX_PLOAD_WIDTH]; //发射数据缓存
void SPI_NRF_Init(void);
u8 SPI_NRF_RW(u8 dat);
u8 SPI_NRF_ReadReg(u8 reg );
u8 SPI_NRF_WriteReg(u8 reg,u8 dat);
u8 SPI_NRF_ReadBuf(u8 reg,u8 *pBuf,u8 bytes);
u8 SPI_NRF_WriteBuf(u8 reg ,u8 *pBuf,u8 bytes);
void NRF_TX_Mode(void);
void NRF_RX_Mode(void);
u8 NRF_Rx_Dat(u8 *rxbuf);
u8 NRF_Tx_Dat(u8 *txbuf);
u8 NRF_Check(void);
#endif /* __NRF24L01_H */
NRF24L01.c 代码如下
#include "./nrf24l01/nrf24l01.h"
#include "./Exti/exti.h"
#include "./usart/bsp_usart.h"
#include "../Hardware/led/bsp_led.h"
u8 RX_BUF[RX_PLOAD_WIDTH]; //接收数据缓存
u8 TX_BUF[TX_PLOAD_WIDTH] = {3,'A','B','C'}; //发射数据缓存
u8 TX_ADDRESS[TX_ADR_WIDTH] = {0xFF,0xFF,0xFF,0xFF,0xFF}; // 定义一个静态发送地址
u8 RX_ADDRESS[RX_ADR_WIDTH] = {0xFF,0xFF,0xFF,0xFF,0xFF};
/**
* @brief SPI的 I/O配置
* @param 无
* @retval 无
*/
void SPI_NRF_Init(void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/*开启相应IO端口的时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA
|NRF_CSN_GPIO_CLK
|NRF_CE_GPIO_CLK
|NRF_IRQ_GPIO_CLK,ENABLE);
/*使能SPI1时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
/*配置 SPI_NRF_SPI的 SCK,MISO,MOSI引脚,GPIOA^5,GPIOA^6,GPIOA^7 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用功能
GPIO_Init(GPIOA, &GPIO_InitStructure);
/*配置SPI_NRF_SPI的CE引脚,和SPI_NRF_SPI的 CSN 引脚*/
GPIO_InitStructure.GPIO_Pin = NRF_CSN_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(NRF_CSN_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = NRF_CE_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(NRF_CE_GPIO_PORT, &GPIO_InitStructure);
/*配置SPI_NRF_SPI的IRQ引脚*/
GPIO_InitStructure.GPIO_Pin = NRF_IRQ_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
GPIO_Init(NRF_IRQ_GPIO_PORT, &GPIO_InitStructure);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //双线全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //主模式
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //数据大小8位
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //时钟极性,空闲时为低
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //第1个边沿有效,上升沿为采样时刻
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由软件产生
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; //8分频,9MHz
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //高位在前
SPI_InitStructure.SPI_CRCPolynomial = 0;
SPI_Init(SPI1, &SPI_InitStructure);
/* Enable SPI1 */
SPI_Cmd(SPI1, ENABLE);
NRF_CE_LOW();
/* 这是自定义的宏,用于拉高csn引脚,NRF进入空闲状态 */
NRF_CSN_HIGH();
}
/**
* @brief 用于向NRF读/写一字节数据
* @param 写入的数据
* @arg dat
* @retval 读取得的数据
*/
u8 SPI_NRF_RW(u8 dat)
{
/* 当 SPI发送缓冲器非空时等待 */
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
/* 通过 SPI2发送一字节数据 */
SPI_I2S_SendData(SPI1, dat);
/* 当SPI接收缓冲器为空时等待 */
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
/* Return the byte read from the SPI bus */
return SPI_I2S_ReceiveData(SPI1);
}
/**
* @brief 用于向NRF特定的寄存器写入数据
* @param
* @arg reg:NRF的命令+寄存器地址
* @arg dat:将要向寄存器写入的数据
* @retval NRF的status寄存器的状态
*/
u8 SPI_NRF_WriteReg(u8 reg,u8 dat)
{
u8 status;
/*置低CSN,使能SPI传输*/
NRF_CSN_LOW();
/*发送命令及寄存器号 */
status = SPI_NRF_RW(reg);
/*向寄存器写入数据*/
SPI_NRF_RW(dat);
/*CSN拉高,完成*/
NRF_CSN_HIGH();
/*返回状态寄存器的值*/
return(status);
}
/**
* @brief 用于从NRF特定的寄存器读出数据
* @param
* @arg reg:NRF的命令+寄存器地址
* @retval 寄存器中的数据
*/
u8 SPI_NRF_ReadReg(u8 reg)
{
u8 reg_val;
/*置低CSN,使能SPI传输*/
NRF_CSN_LOW();
/*发送寄存器号*/
SPI_NRF_RW(reg);
/*读取寄存器的值 */
reg_val = SPI_NRF_RW(NOP);
/*CSN拉高,完成*/
NRF_CSN_HIGH();
return reg_val;
}
/**
* @brief 用于向NRF的寄存器中写入一串数据
* @param
* @arg reg : NRF的命令+寄存器地址
* @arg pBuf:用于存储将被读出的寄存器数据的数组,外部定义
* @arg bytes: pBuf的数据长度
* @retval NRF的status寄存器的状态
*/
u8 SPI_NRF_ReadBuf(u8 reg,u8 *pBuf,u8 bytes)
{
u8 status, byte_cnt;
/*置低CSN,使能SPI传输*/
NRF_CSN_LOW();
/*发送寄存器号*/
status = SPI_NRF_RW(reg);
/*读取缓冲区数据*/
for(byte_cnt=0; byte_cnt < bytes; byte_cnt++)
pBuf[byte_cnt] = SPI_NRF_RW(NOP); //从NRF24L01读取数据
/*CSN拉高,完成*/
NRF_CSN_HIGH();
return status; //返回寄存器状态值
}
/**
* @brief 用于向NRF的寄存器中写入一串数据
* @param
* @arg reg : NRF的命令+寄存器地址
* @arg pBuf:存储了将要写入写寄存器数据的数组,外部定义
* @arg bytes: pBuf的数据长度
* @retval NRF的status寄存器的状态
*/
u8 SPI_NRF_WriteBuf(u8 reg ,u8 *pBuf,u8 bytes)
{
u8 status,byte_cnt;
/*置低CSN,使能SPI传输*/
NRF_CSN_LOW();
/*发送寄存器号*/
status = SPI_NRF_RW(reg);
/*向缓冲区写入数据*/
for(byte_cnt = 0; byte_cnt < bytes; byte_cnt++)
SPI_NRF_RW(*pBuf++); //写数据到缓冲区
/*CSN拉高,完成*/
NRF_CSN_HIGH();
return (status); //返回NRF24L01的状态
}
/**
* @brief 配置并进入接收模式
* @param 无
* @retval 无
*/
void NRF_RX_Mode(void)
{
NRF_CE_LOW();
SPI_NRF_WriteBuf(NRF_WRITE_REG+RX_ADDR_P0,RX_ADDRESS,RX_ADR_WIDTH);//写RX节点地址
SPI_NRF_WriteReg(NRF_WRITE_REG+EN_AA,0x01); //使能通道0的自动应答
SPI_NRF_WriteReg(NRF_WRITE_REG+EN_RXADDR,0x01);//使能通道0的接收地址
SPI_NRF_WriteReg(NRF_WRITE_REG+RF_CH,CHANAL); //设置RF通信频率
SPI_NRF_WriteReg(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//选择通道0的有效数据宽度
SPI_NRF_WriteReg(NRF_WRITE_REG+RF_SETUP,0x0f); //设置TX发射参数,0db增益,2Mbps,低噪声增益开启
SPI_NRF_WriteReg(NRF_WRITE_REG+CONFIG, 0x0f); //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式
/*CE拉高,进入接收模式*/
NRF_CE_HIGH();
}
/**
* @brief 配置发送模式
* @param 无
* @retval 无
*/
void NRF_TX_Mode(void)
{
NRF_CE_LOW();
SPI_NRF_WriteBuf(NRF_WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH); //写TX节点地址
SPI_NRF_WriteBuf(NRF_WRITE_REG+RX_ADDR_P0,RX_ADDRESS,RX_ADR_WIDTH); //设置RX节点地址,主要为了使能ACK
SPI_NRF_WriteReg(NRF_WRITE_REG+EN_AA,0x01); //使能通道0的自动应答
SPI_NRF_WriteReg(NRF_WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址
SPI_NRF_WriteReg(NRF_WRITE_REG+SETUP_RETR,0x1a);//设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次
SPI_NRF_WriteReg(NRF_WRITE_REG+RF_CH,CHANAL); //设置RF通道为CHANAL
SPI_NRF_WriteReg(NRF_WRITE_REG+RF_SETUP,0x0f); //设置TX发射参数,0db增益,2Mbps,低噪声增益开启
SPI_NRF_WriteReg(NRF_WRITE_REG+CONFIG,0x0e); //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,发射模式,开启所有中断
/*CE拉高,进入发送模式*/
NRF_CE_HIGH();
//Delay(0xffff); //CE要拉高一段时间才进入发送模式
}
/**
* @brief 主要用于NRF与MCU是否正常连接
* @param 无
* @retval SUCCESS/ERROR 连接正常/连接失败
*/
u8 NRF_Check(void)
{
u8 buf[5]={0xC2,0xC2,0xC2,0xC2,0xC2};
u8 buf1[5];
u8 i;
/*写入5个字节的地址. */
SPI_NRF_WriteBuf(NRF_WRITE_REG+TX_ADDR,buf,5);
/*读出写入的地址 */
SPI_NRF_ReadBuf(TX_ADDR,buf1,5);
/*比较*/
for(i=0;i<5;i++)
{
if(buf1[i]!=0xC2)
break;
}
if(i==5)
return SUCCESS ; //MCU与NRF成功连接
else
return ERROR ; //MCU与NRF不正常连接
}
/**
* @brief 用于向NRF的发送缓冲区中写入数据
* @param
* @arg txBuf:存储了将要发送的数据的数组,外部定义
* @retval 发送结果,成功返回TXDS,失败返回MAXRT或ERROR
*/
u8 NRF_Tx_Dat(u8 *txbuf)
{
u8 state;
/*ce为低,进入待机模式1*/
NRF_CE_LOW();
/*写数据到TX BUF 最大 32个字节*/
SPI_NRF_WriteBuf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);
/*CE为高,txbuf非空,发送数据包 */
NRF_CE_HIGH();
/*等待发送完成中断 */
while(NRF_Read_IRQ() != 0);
/*读取状态寄存器的值 */
state = SPI_NRF_ReadReg(STATUS);
/*清除TX_DS或MAX_RT中断标志*/
SPI_NRF_WriteReg(NRF_WRITE_REG+STATUS, state);
SPI_NRF_WriteReg(FLUSH_TX,NOP); //清除TX FIFO寄存器
/*判断中断类型*/
if(state&MAX_RT) //达到最大重发次数
return MAX_RT;
else if(state&TX_DS) //发送完成
return TX_DS;
else
return ERROR; //其他原因发送失败
}
/**
* @brief 用于从NRF的接收缓冲区中读出数据
* @param
* @arg rxBuf :用于接收该数据的数组,外部定义
* @retval
* @arg 接收结果
*/
u8 NRF_Rx_Dat(u8 *rxbuf)
{
u8 state;
NRF_CE_HIGH(); //进入接收状态
/*等待接收中断*/
while(NRF_Read_IRQ() == 0)
{LED2_ON;
NRF_CE_LOW(); //进入待机状态
/*读取status寄存器的值 */
state = SPI_NRF_ReadReg(STATUS);
/* 清除中断标志*/
SPI_NRF_WriteReg(NRF_WRITE_REG+STATUS,state);
/*判断是否接收到数据*/
if(state&RX_DR) //接收到数据
{
SPI_NRF_ReadBuf(RD_RX_PLOAD, rxbuf, RX_PLOAD_WIDTH);//读取数据
SPI_NRF_WriteReg(FLUSH_RX, NOP); //清除RX FIFO寄存器
return RX_DR;
}
else
return ERROR; //没收到任何数据
}
return ERROR; //没收到任何数据
}
/*********************************************END OF FILE**********************/
main.c 的代码如下:
#include "stm32f10x.h"
#include "./usart/bsp_usart.h"
#include "./nrf24l01/nrf24l01.h"
/*
* 函数名:main
* 描述 :主函数
* 输入 :无
* 输出 :无
*/
int main(void)
{
uint8_t flag = 0;
/* 配置串口为:115200 8-N-1 */
USART_Config();
SPI_NRF_Init();
if(NRF_Check() == SUCCESS)
{
printf("\r\n检测到NRF24L01");
}
NRF_TX_Mode();
flag = SPI_NRF_ReadReg(STATUS);
printf("\r\nflag = 0x%02X",flag);
flag = NRF_Tx_Dat(TX_BUF);
printf("\r\nflag = 0x%02X",flag);
NRF_RX_Mode();
flag = SPI_NRF_ReadReg(STATUS);
printf("\r\nflag = 0x%02X",flag);
while(1)
{
/*读取status寄存器的值 */
flag = SPI_NRF_ReadReg(STATUS);
/* 清除中断标志*/
SPI_NRF_WriteReg(NRF_WRITE_REG+STATUS, flag);
/*判断是否接收到数据*/
if(flag & RX_DR) //接收到数据
{
SPI_NRF_ReadBuf(RD_RX_PLOAD, RX_BUF, RX_PLOAD_WIDTH);//读取数据
SPI_NRF_WriteReg(FLUSH_RX, NOP); //清除RX FIFO寄存器
printf("\r\n成功接收到数据!");
}
}