基于51单片机的NRF24L01通讯问题。

2019-07-18 14:36发布

网上买的开发板,NRF模块也是淘宝买的。程序自己弄来弄去有两个月了,就是不能通信,求助。两端代码发在下面,求好心人帮忙。要哭了。

发送代码:
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define TX_ADDR_WITDH 5 //发送地址宽度设置为5个字节
#define RX_ADDR_WITDH 5 //接收地址宽度设置为5个字节
#define TX_DATA_WITDH 2 //发送数据宽度
#define RX_DATA_WITDH 2 //接收数据宽度


//以下为命令寄存器
#define R_REGISTER 0x00 // 读寄存器
#define W_REGISTER 0x20 // 写寄存器
#define R_RX_PLOAD 0x61 // 读RX FIFO有效数据,1-32字节,当读数据完成后,数据被清除,应用于接收模式
#define W_TX_PLOAD 0xA0 // 写TX FIFO有效数据,1-32字节,写操作从字节0开始,应用于发射模式
#define FLUSH_TX 0xE1 // 清除TX FIFO寄存器,应用于发射模式
#define FLUSH_RX 0xE2 // 清除RX FIFO寄存器,应用于接收模式
#define REUSE_TX_PL 0xE3 // 重新使用上一包有效数据,当CE为高过程中,数据包被不断的重新发射
#define NOP 0xFF // 空操作,可以用来读状态寄存器


//以下为寄存器地址
#define CONFIG 0x00 // 配置寄存器
#define EN_AA 0x01 // “自动应答”功能寄存
#define EN_RX_ADDR 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 // 数据通道0接收地址寄存器
#define RX_ADDR_P1 0x0B // 数据通道1接收地址寄存器
#define RX_ADDR_P2 0x0C // 数据通道2接收地址寄存器
#define RX_ADDR_P3 0x0D // 数据通道3接收地址寄存器
#define RX_ADDR_P4 0x0E // 数据通道4接收地址寄存器
#define RX_ADDR_P5 0x0F // 数据通道5接收地址寄存器
#define TX_ADDR 0x10 // 发送地址寄存器
#define RX_PW_P0 0x11 // 数据通道0有效数据宽度设置寄存器
#define RX_PW_P1 0x12 // 数据通道1有效数据宽度设置寄存器
#define RX_PW_P2 0x13 // 数据通道2有效数据宽度设置寄存器
#define RX_PW_P3 0x14 // 数据通道3有效数据宽度设置寄存器
#define RX_PW_P4 0x15 // 数据通道4有效数据宽度设置寄存器
#define RX_PW_P5 0x16 // 数据通道5有效数据宽度设置寄存器
#define FIFO_STATUS 0x17 // FIFO状态寄存器


//nRF24L01引脚定义
sbit MISO=P2^0;
sbit SCK=P3^6;
sbit MOSI=P2^2;
sbit CE=P3^3;
sbit CSN=P3^7;
sbit IRQ=P2^1;

//外围引脚定义
sbit LED=P2^7;




uchar code TX_Addr[TX_ADDR_WITDH]={0x34,0x43,0x10,0x10,0x01};
uchar code RX_Addr[RX_ADDR_WITDH]={0x34,0x43,0x10,0x10,0x01};
uchar RX_Buffer[RX_DATA_WITDH]={0};
uchar m=0;







void _delay_ms(int x)
{
int i,j;
for (j=0;j<x;j++)
  for (i=0;i<120;i++);
}




//SPI时序函数(1)
uchar SPI_RW(uchar byte)
{
uchar i,temp;
temp=0;
SCK=0;
for(i=0;i<8;i++)
{
if(byte&0x80)
    MOSI=1;
else
    MOSI=0;
        byte<<=1;
        SCK=1;
        _nop_();
        _nop_();
        temp<<=1;
        if(MISO)
        temp++;
        SCK=0;
        _nop_();
        _nop_();
}
return temp;
}



//往寄存器写一字节(2)
uchar SPI_W_Reg(uchar reg,uchar value)
{
uchar status;//返回状态
CSN=0;//SPI片选
status=SPI_RW(reg);//写入寄存器地址,同时读取状态
SPI_RW(value);//写入一字节
CSN=1;//
return status;//返回状态
}



//从寄存器中读一字节(3)
uchar SPI_R_byte(uchar reg)
{
uchar reg_value;
CSN=0;
SPI_RW(reg);
reg_value=SPI_RW(0);
CSN=1;
return reg_value;
}





//往寄存器中写多个字节(5)
uchar SPI_W_DBuffer(uchar reg,uchar *TX_Dat_Buffer,uchar Dlen)
{
uchar status,i;
CSN=0;
status=SPI_RW(reg);
_delay_ms(30);
for(i=0;i<Dlen;i++)//uart_delay(10)
{
SPI_RW(*TX_Dat_Buffer++);
}
CSN=1;
return status;
}


void nrf2401_TX_Mode()
{
CE=0;
SPI_W_DBuffer(W_REGISTER+TX_ADDR,TX_Addr,TX_ADDR_WITDH);//本机地址
SPI_W_DBuffer(W_REGISTER+RX_ADDR_P0,RX_Addr,TX_ADDR_WITDH);//接收地址

SPI_W_Reg(W_REGISTER+RX_PW_P0,RX_DATA_WITDH);//接收数据长度
SPI_W_Reg(W_REGISTER+EN_AA,0x01); //自动应答
SPI_W_Reg(W_REGISTER+EN_RX_ADDR,0x01);//通道一
SPI_W_Reg(W_REGISTER+SETUP_RETR,0x1a);
SPI_W_Reg(W_REGISTER+RF_CH,0);//频道
SPI_W_Reg(W_REGISTER+RF_SETUP,0x07);//发射率速
SPI_W_Reg(W_REGISTER+CONFIG,0x0e);
CE=1;
}

void main()
{
uchar sta;
nrf2401_TX_Mode();
_delay_ms(200);
while(1)
   {
    CE=0;
    SPI_W_DBuffer( W_TX_PLOAD,TX_Addr,TX_ADDR_WITDH);
        CE=1;
        while(IRQ)
        sta=SPI_R_byte(STATUS);
        SPI_W_Reg(FLUSH_TX,0xff);
        SPI_W_Reg(W_REGISTER+STATUS,sta);
    _delay_ms(1000);
   }
}




接收代码:
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define TX_ADDR_WITDH 5 //发送地址宽度设置为5个字节
#define RX_ADDR_WITDH 5 //接收地址宽度设置为5个字节
#define TX_DATA_WITDH 2 //发送数据宽度
#define RX_DATA_WITDH 2 //接收数据宽度


//以下为命令寄存器
#define R_REGISTER 0x00 // 读寄存器
#define W_REGISTER 0x20 // 写寄存器
#define R_RX_PLOAD 0x61 // 读RX FIFO有效数据,1-32字节,当读数据完成后,数据被清除,应用于接收模式
#define W_TX_PLOAD 0xA0 // 写TX FIFO有效数据,1-32字节,写操作从字节0开始,应用于发射模式
#define FLUSH_TX 0xE1 // 清除TX FIFO寄存器,应用于发射模式
#define FLUSH_RX 0xE2 // 清除RX FIFO寄存器,应用于接收模式
#define REUSE_TX_PL 0xE3 // 重新使用上一包有效数据,当CE为高过程中,数据包被不断的重新发射
#define NOP 0xFF // 空操作,可以用来读状态寄存器


//以下为寄存器地址
#define CONFIG 0x00 // 配置寄存器
#define EN_AA 0x01 // “自动应答”功能寄存
#define EN_RX_ADDR 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 // 数据通道0接收地址寄存器
#define RX_ADDR_P1 0x0B // 数据通道1接收地址寄存器
#define RX_ADDR_P2 0x0C // 数据通道2接收地址寄存器
#define RX_ADDR_P3 0x0D // 数据通道3接收地址寄存器
#define RX_ADDR_P4 0x0E // 数据通道4接收地址寄存器
#define RX_ADDR_P5 0x0F // 数据通道5接收地址寄存器
#define TX_ADDR 0x10 // 发送地址寄存器
#define RX_PW_P0 0x11 // 数据通道0有效数据宽度设置寄存器
#define RX_PW_P1 0x12 // 数据通道1有效数据宽度设置寄存器
#define RX_PW_P2 0x13 // 数据通道2有效数据宽度设置寄存器
#define RX_PW_P3 0x14 // 数据通道3有效数据宽度设置寄存器
#define RX_PW_P4 0x15 // 数据通道4有效数据宽度设置寄存器
#define RX_PW_P5 0x16 // 数据通道5有效数据宽度设置寄存器
#define FIFO_STATUS 0x17 // FIFO状态寄存器


//nRF24L01引脚定义
sbit MISO=P2^0;
sbit SCK=P3^6;
sbit MOSI=P2^2;
sbit CE=P3^3;
sbit CSN=P3^7;

//外围引脚定义
sbit LED=P2^7;




uchar code TX_Addr[TX_ADDR_WITDH]={0x34,0x43,0x10,0x10,0x01};
uchar code RX_Addr[RX_ADDR_WITDH]={0x34,0x43,0x10,0x10,0x01};
uchar RX_Buffer[RX_DATA_WITDH]={0};
uchar m=0;




void _delay_ms(int x)
{
int i,j;
for (j=0;j<x;j++)
  for (i=0;i<120;i++);
}




//SPI时序函数(1)
uchar SPI_RW(uchar byte)
{
uchar i;
SCK=0;
for(i=0;i<8;i++)
{
MOSI=(byte&0x80);
byte=(byte<<1);
SCK=1;
byte|=MISO;
SCK=0;
}
return(byte);
}



//往寄存器写一字节(2)
uchar SPI_W_Reg(uchar reg,uchar value)//reg为寄存器地址,value为要写入寄存器的值
{
uchar status;//返回状态
CSN=0;//SPI片选
status=SPI_RW(reg);//写入寄存器地址,同时读取状态
SPI_RW(value);//写入一字节
CSN=1;//
return status;//返回状态
}



//从寄存器中读一字节(3)
uchar SPI_R_byte(uchar reg)
{
uchar reg_value;
CSN=0;
SPI_RW(reg);
reg_value=SPI_RW(0);
CSN=1;
return reg_value;
}



//从寄存器中读多个字节(4)
uchar SPI_R_DBuffer(uchar reg,uchar *Dat_Buffer,uchar Dlen)
{
uchar status,i;
CSN=0;
status=SPI_RW(reg);
for(i=0;i<Dlen;i++)
{
Dat_Buffer[i]=SPI_RW(0);
}
CSN=1;
return status;
}



//往寄存器中写多个字节(5)
uchar SPI_W_DBuffer(uchar reg,uchar *TX_Dat_Buffer,uchar Dlen)
{
uchar status,i;
CSN=0;
status=SPI_RW(reg);
_delay_ms(30);
for(i=0;i<Dlen;i++)//uart_delay(10)
{
SPI_RW(*TX_Dat_Buffer++);
}
CSN=1;
return status;
}


void nrf2401_RX_Mode()
{
CE=0;
SPI_W_DBuffer(W_REGISTER+TX_ADDR,TX_Addr,TX_ADDR_WITDH);//本机地址
SPI_W_DBuffer(W_REGISTER+RX_ADDR_P0,RX_Addr,RX_ADDR_WITDH);//接收地址

SPI_W_Reg(W_REGISTER+EN_AA,0x01); //自动应答
SPI_W_Reg(W_REGISTER+EN_RX_ADDR,0x01);//通道一
SPI_W_Reg(W_REGISTER+RF_CH,0x30);//频道
SPI_W_Reg(W_REGISTER+RX_PW_P0,RX_DATA_WITDH);//接收数据长度
SPI_W_Reg(W_REGISTER+RF_SETUP,0x07);//发射率速
SPI_W_Reg(W_REGISTER+CONFIG,0x0f);
CE=1;
}

void main()
{
uchar sta;
LED=0;
nrf2401_RX_Mode();
_delay_ms(1000);
    while(1)
          {
           sta=SPI_R_byte(STATUS);
           if((sta&0x40)!=0)
        SPI_R_DBuffer(R_RX_PLOAD,RX_Buffer,RX_ADDR_WITDH);
                   if((RX_Buffer[0]==0x34)&&(RX_Buffer[1]==0x43)&&(RX_Buffer[2]==0x10)&&(RX_Buffer[3]==10)&&(RX_Buffer[4]==0x01))
                LED=1;
         SPI_W_Reg(FLUSH_RX,0xff);
                 SPI_W_Reg(W_REGISTER+STATUS,sta);
                  _delay_ms(1000);
          }
}

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