STM32硬件SPI驱动NRF24L01,测试发送成功,但是一直没有接收到数据

2019-07-15 15:01发布

本帖最后由 逗比的狼 于 2016-2-3 12:38 编辑

两个单片机接两个NRF24L01,一发送一接受。代码如下:
#include "NRF24L01.H"

// PA3 --- CE, PA4 --- CSN, PA5 --- CLK, PA6 --- MISO, PA7 --- MOSI, PA8 --- IRQ
//CE,CSN,IQR操作函数   
#define CE_L            GPIO_ResetBits(GPIOA, GPIO_Pin_3)
#define CE_H            GPIO_SetBits(GPIOA, GPIO_Pin_3)
#define CSN_L            GPIO_ResetBits(GPIOA, GPIO_Pin_4)
#define CSN_H            GPIO_SetBits(GPIOA, GPIO_Pin_4)
#define READ_IRQ    GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8)

uint8_t RX_TX_ADDR[RX_TX_ADDR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; //发送、接收地址

void NRF_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
  SPI_InitTypeDef SPI_InitStructure;
   
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
   
  //  PA5 --- CLK, PA7 --- MOSI
  GPIO_InitStructure.GPIO_Pin         =    GPIO_Pin_5 | GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode         =    GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed     = GPIO_Speed_10MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  //    PA6 --- MISO
  GPIO_InitStructure.GPIO_Pin         = GPIO_Pin_6;
  GPIO_InitStructure.GPIO_Mode         = GPIO_Mode_IN_FLOAtiNG;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  //  PA3 --- CE, PA4 --- CSN
  GPIO_InitStructure.GPIO_Pin         = GPIO_Pin_3 | GPIO_Pin_4;
  GPIO_InitStructure.GPIO_Mode         = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed     = GPIO_Speed_10MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
    // PA8 --- IRQ
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;  
  GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPU;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

    CE_L;
    CSN_H;
                                   
  SPI_InitStructure.SPI_Direction                 = SPI_Direction_2Lines_FullDuplex;
  SPI_InitStructure.SPI_Mode                             = SPI_Mode_Master;                    
  SPI_InitStructure.SPI_DataSize                     = SPI_DataSize_8b;               
  SPI_InitStructure.SPI_CPOL                             = SPI_CPOL_Low;                       
  SPI_InitStructure.SPI_CPHA                             = SPI_CPHA_1Edge;                     
  SPI_InitStructure.SPI_NSS                             = SPI_NSS_Soft;                        
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
  SPI_InitStructure.SPI_FirstBit                     =    SPI_FirstBit_MSB;      
  SPI_InitStructure.SPI_CRCPolynomial         = 7;                          
    SPI_Init(SPI1,&SPI_InitStructure);                                 
  
    SPI_Cmd(SPI1, ENABLE);
}

uint8_t SPI_ReadWriteByte(uint8_t byte)
{
    uint8_t retry = 0;
    while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET)
    {
        if(retry++ > 200)
            return 0;
    }
    retry = 0;
    SPI_I2S_SendData(SPI1, byte);
    while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET)
    {
        if(retry++ > 200)
            return 0;
    }
    return SPI_I2S_ReceiveData(SPI1);
}


uint8_t    NRF_ReadReg(uint8_t reg)
{
    uint8_t data;
    CE_L;
    CSN_L;                                                        //使能SPI传输
    SPI_ReadWriteByte(reg);                        //发送寄存器地址
    data = SPI_ReadWriteByte(0xFF);        //读出寄存器数据
    CSN_H;                                                        //失能SPI传输
    return data;   
}

uint8_t    NRF_WriteReg(uint8_t reg, uint8_t data)
{
    uint8_t status;
    CE_L;
    CSN_L;                                                            //使能SPI传输
    status = SPI_ReadWriteByte(reg);        //发送寄存器地址,并接收状态值
    SPI_ReadWriteByte(data);                        //写入寄存器数据
    CSN_H;                                                            //失能SPI传输
    return status;
}

uint8_t    NRF_ReadBuf(uint8_t reg, uint8_t *pBuf, uint8_t len)
{
    uint8_t i, status;
    CE_L;
    CSN_L;                                                            //使能SPI传输
    status = SPI_ReadWriteByte(reg);        //发送寄存器地址,并接收状态值
    for(i = 0; i < len; i++)                        
        pBuf = SPI_ReadWriteByte(0xFF);//读出缓冲区数据
    CSN_H;                                                            //失能SPI传输
    return status;
}

uint8_t    NRF_WriteBuf(uint8_t reg, uint8_t *pBuf, uint8_t len)
{
    uint8_t i, status;
    CE_L;
    CSN_L;                                                            //使能SPI传输
    status = SPI_ReadWriteByte(reg);        //发送寄存器地址,并接收状态值
    for(i = 0; i < len; i++)
        SPI_ReadWriteByte(pBuf);                //写入缓冲区数据
    CSN_H;                                                            //失能SPI传输
    return status;
}

uint8_t NRF_Check(void)
{
    uint8_t i, buf[5] = {0xA5, 0xA5, 0xA5, 0xA5, 0xA5};
    NRF_WriteBuf(WR_REG+TX_ADDR,buf,5);    //写入5个字节的地址.
    NRF_ReadBuf(TX_ADDR,buf,5);                         //读出写入的地址
    for(i = 0; i < 5; i++)
        if(buf != 0xA5)
            break;
    if(i != 5)
        return 0;                                                                    //检测NRF错误
    return 1;                                                                        //检测到NRF
}

void NRF_RxMode(void)
{
    CE_L;
    NRF_WriteReg(WR_REG + SETUP_AW, 0x03);                                                        //设置发送地址宽度:5字节   
    NRF_WriteBuf(WR_REG + TX_ADDR, RX_TX_ADDR, RX_TX_ADDR_WIDTH);            //写TX节点地址            
    NRF_WriteBuf(WR_REG + RX_ADDR_P0, RX_TX_ADDR, RX_TX_ADDR_WIDTH);    //写RX节点地址                        
   
    //NRF_WriteReg(WR_REG + EN_AA, 0x01);                                                                //使能接收通道0的自动应答
    NRF_WriteReg(WR_REG + EN_AA, 0x00);                                                                //关闭接收通道0的自动应答
    NRF_WriteReg(WR_REG + EN_RXADDR, 0x01);                                                        //使能接收通道0的接收地址
    NRF_WriteReg(WR_REG + SETUP_RETR, 0x1A);                                                    //设置自动重发时间间隔:500+86us,最大自动重发次数:10次   
   
    NRF_WriteReg(WR_REG + RF_CH, 40);                                                                    //设置RF通信频率
    NRF_WriteReg(WR_REG + RF_SETUP, 0x0F);                                                        //设置TX发射参数,0dB增益,2Mbps,低噪声增益开启
    NRF_WriteReg(WR_REG + RX_PW_P0, RX_TX_PLOAD_WIDTH);                                //设置通道0的有效数据宽度
   
    NRF_WriteReg(WR_REG + NRF_CONFIG, 0x0F);                                                    //配置工作模式参数,PWR_UP,EN_CRC,16BIT_CRC,接受模式,中断全开   
    CE_H;                                                                                                                            //CE高,进入接收模式
    Delay(1);
}

void NRF_TxMode(void)
{
    CE_L;
    NRF_WriteReg(WR_REG + SETUP_AW, 0x03);                                                        //设置发送地址宽度:5字节   
    NRF_WriteBuf(WR_REG + TX_ADDR, RX_TX_ADDR, RX_TX_ADDR_WIDTH);            //写TX节点地址            
    NRF_WriteBuf(WR_REG + RX_ADDR_P0, RX_TX_ADDR, RX_TX_ADDR_WIDTH);    //写RX节点地址                        
    //关闭自动应答,自动重发,测试用   
    NRF_WriteReg(WR_REG + EN_AA, 0x00);            //NRF_WriteReg(WR_REG + EN_AA, 0x01);                                                                //使能接收通道0的自动应答
    NRF_WriteReg(WR_REG + EN_RXADDR, 0x00);    //NRF_WriteReg(WR_REG + EN_RXADDR, 0x01);                                                        //使能接收通道0的接收地址
    NRF_WriteReg(WR_REG + SETUP_RETR, 0x00);//NRF_WriteReg(WR_REG + SETUP_RETR, 0x1A);                                                    //设置自动重发时间间隔:500+86us,最大自动重发次数:10次   
   
    NRF_WriteReg(WR_REG + RF_CH, 40);                                                                    //设置RF通信频率
    NRF_WriteReg(WR_REG + RF_SETUP, 0x0F);                                                        //设置TX发射参数,0dB增益,2Mbps,低噪声增益开启
   
    NRF_WriteReg(WR_REG + NRF_CONFIG, 0x0E);                                                    //配置工作模式参数,PWR_UP,EN_CRC,16BIT_CRC,发射模式,中断全开   
    CE_H;                                                                                                                            //CE高,进入发射模式
    Delay(1);
}

uint8_t NRF_TestTx(uint8_t data)
{
    uint8_t status = 0;
    do
    {   
        CE_L;
        NRF_WriteReg(WR_TX_PLOAD, data);
        CE_H;
        Delay(1);
        if(status++ > 250)
            break;
    }while(READ_IRQ != 0);
    NRF_WriteReg(FLUSH_TX, NOP);
    CE_L;
    Delay(1);
    status =  NRF_ReadReg(RD_REG + STATUS);
    NRF_WriteReg(WR_REG + STATUS, status);
    return status;   
}

uint8_t NRF_TestRx(void)
{
    uint8_t data = 0;
    while(READ_IRQ != 0)
    {
        if(data++ > 250)
            break;
    }
    CE_L;
    Delay(1);
    data = NRF_ReadReg(RD_REG + STATUS);
    NRF_WriteReg(WR_REG + STATUS, data);
    return data;   
}
发送端:
    NRF_Init();
    NRF_TxMode();
    if(NRF_Check() == 0)
        USART_SendString(USART1, "ERROR");
    else
        USART_SendString(USART1, "OK");
然后每隔100ms执行
    GPIO_WriteBit(GPIOB, GPIO_Pin_0, ((BitAction)(1 - GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_0))));
    USART_SendNum(USART1, (NRF_TestTx(0x01)), 0);
    USART_SendString(USART1, " ");   
串口接收到46即0x2E,说明数据发送出去了
接收端:
    NRF_Init();
    NRF_RxMode();
    if(NRF_Check() == 0)
        USART_SendString(USART1, "ERROR");
    else
        USART_SendString(USART1, "OK");
每隔100ms执行
    GPIO_WriteBit(GPIOB, GPIO_Pin_0, ((BitAction)(1 - GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_0))));
    USART_SendNum(USART1, (NRF_TestRx()), 0);
    USART_SendString(USART1, " ");
串口只能接收到14即0x0E,接收一直不成功。
求大神帮忙看看是不是代码设置的有问题。

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。