求解:nRF24L01无线模块无法通信,求解答

2019-07-15 19:26发布

网购了两个nRF24l01模块,想做无线收发功能,控制器分别为89C52和STC12c5A60s2,无线模块接口接在P0口,IRQ接到单片机P3^2,求助,接收端收不到信息,附程序,求大神解释一下~~~~~好几天还没解决;

接收端程序:
#include<reg52.h>
#include<api.h>
#define uint unsigned int
#define uchar unsigned char
#define LED P1
sbit key=P3^7;
/***************************************************/
#define TX_ADR_WIDTH   5  // 5字节宽度的发送/接收地址
#define TX_PLOAD_WIDTH 4  // 数据通道有效数据宽度

uchar code TX_ADDRESS[TX_ADR_WIDTH] = {0x34,0x43,0x10,0x10,0x01};  // 定义一个静态发送地址
uchar RX_BUF[TX_PLOAD_WIDTH];
uchar TX_BUF[TX_PLOAD_WIDTH];
uchar flag;
uchar DATA = 0x01;
uchar bdata sta;
sbit  RX_DR     = sta^6;
sbit  TX_DS     = sta^5;
sbit  MAX_RT = sta^4;
/**************************************************
函数: init_io()

描述:
    初始化IO
/**************************************************/
void init_io(void)
{
    CE  = 0;        // 待机
    CSN = 1;        // SPI禁止
    SCK = 0;        // SPI时钟置低
    IRQ = 1;        // 中断复位
//    LED = 0xff;        // 关闭指示灯
}
/**************************************************
函数:delay()

描述:延时函数
**************************************************/
void delay(uint z)
{
    uint x;
    while(z--)
        for(x=110;x>0;x--);
}
/**************************************************
函数:SPI_RW()

描述:
    根据SPI协议,写一字节数据到nRF24L01,同时从nRF24L01
    读出一字节
/**************************************************/
uchar SPI_RW(uchar byte)
{
    uchar i;
    for(i=0;i<8;i++)
    {
        MOSI=(byte&0x80);
        byte<<=1;
        SCK=1;
        byte|=MISO;
        SCK=0;
    }
    return (byte);
}
/**************************************************
函数:SPI_RW_Reg()

描述:
    写数据value到reg寄存器
/**************************************************/
uchar SPI_RW_REG(uchar reg,uchar value)
{
    uchar status;
    CSN=0;
    status=SPI_RW(reg);
    SPI_RW(value);
    CSN=1;
    return(status);
}
/**************************************************
函数:SPI_Read()

描述:
    从reg寄存器读一字节
/**************************************************/
uchar SPI_READ(uchar reg)
{
    uchar status,reg_val;
    CSN=0;
    SPI_RW(reg);
    reg_val=SPI_RW(0);
    CSN=1;
    return(status);
}
/**************************************************
函数:SPI_Read_Buf()

描述:
    从reg寄存器读出bytes个字节,通常用来读取接收通道
    数据或接收/发送地址
/**************************************************/
uchar SPI_READ_BUF(uchar reg,uchar *pBUF,uchar byte)
{
    uchar status,i;
    CSN=0;
    status=SPI_RW(reg);
    for(i=0;i<byte;i++)
    {
        pBUF[i]=SPI_RW(0);
    }
    CSN=1;
    return(status);
}
/**************************************************
函数:SPI_Write_Buf()

描述:
    把pBuf缓存中的数据写入到nRF24L01,通常用来写入发
    射通道数据或接收/发送地址
/**************************************************/
uchar SPI_WRITE_BUF(uchar reg,uchar *pBUF,uchar byte)
{
    uchar status,i;
    CSN=0;
    status=SPI_RW(reg);
    for(i=0;i<byte;i++)
        SPI_RW(*pBUF++);
    CSN=1;
    return(status);   
}
/**************************************************
函数:RX_Mode()

描述:
    这个函数设置nRF24L01为接收模式,等待接收发送设备的数据包
/**************************************************/
void RX_MODE()
{
    CE=0;
    SPI_WRITE_BUF(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH);
    SPI_RW_REG(WRITE_REG+EN_AA,0X01);
    SPI_RW_REG(WRITE_REG+EN_RXADDR,0X01);
    SPI_RW_REG(WRITE_REG+RF_CH,40);
    SPI_RW_REG(WRITE_REG+RX_PW_P0,TX_PLOAD_WIDTH);
    SPI_RW_REG(WRITE_REG+RF_SETUP,0X07);
    SPI_RW_REG(WRITE_REG+CONFIG,0x0f);
    CE=1;
}
/**************************************************
函数:TX_Mode()

描述:
    这个函数设置nRF24L01为发送模式,(CE=1持续至少10us),
    130us后启动发射,数据发送结束后,发送模块自动转入接收
    模式等待应答信号。
/**************************************************/
void TX_MODE(uchar *BUF)
{
    CE=0;
    SPI_WRITE_BUF(WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH);
    SPI_WRITE_BUF(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH);
    SPI_WRITE_BUF(WR_TX_PLOAD,BUF,TX_PLOAD_WIDTH);
    SPI_RW_REG(WRITE_REG+EN_AA,0X01);
    SPI_RW_REG(WRITE_REG+EN_RXADDR,0X01);
    SPI_RW_REG(WRITE_REG+SETUP_RETR,0X1A);
    SPI_RW_REG(WRITE_REG+RF_CH,40);
    SPI_RW_REG(WRITE_REG+RF_SETUP,0X07);
    SPI_RW_REG(WRITE_REG+CONFIG,0x0E);
    CE=1;
}
/**************************************************
函数:Check_ACK()

描述:
    检查接收设备有无接收到数据包,设定没有收到应答信
    号是否重发
/**************************************************/
uchar Check_ACK(bit clear)
{
    while(IRQ);
    sta = SPI_RW(NOP);                    // 返回状态寄存器
    if(MAX_RT)
        if(clear)                         // 是否清除TX FIFO,没有清除在复位MAX_RT中断标志后重发
            SPI_RW(FLUSH_TX);
    SPI_RW_REG(WRITE_REG + STATUS, sta);  // 清除TX_DS或MAX_RT中断标志
    IRQ = 1;
    if(TX_DS)
        return(0x00);
    else
        return(0xff);
}
/**************************************************
函数:keyscan()

描述:检测是否有按键按下,按下则发送一字节数据
**************************************************
void keyscan()
{
    if(key==0)
    {
        delay(5);
        if(key==0)
        {
            TX_BUF[0]=~DATA;
            TX_MODE(TX_BUF);
            LED=~DATA;
            Check_ACK(1);
            delay(500);
            LED=0XFF;
            while(!key);
            DATA<<=1;
            if(!DATA)
                DATA=0x01;   
        }
    }
}
************************************************/
void main()
{
    init_io();
    RX_MODE();
    while(1)
    {
        sta=SPI_READ(STATUS);
        if(RX_DR)
        {
            SPI_READ_BUF(RD_RX_PLOAD,RX_BUF,TX_PLOAD_WIDTH);
            flag=1;
        }
        SPI_RW_REG(WRITE_REG+STATUS,sta);
        if(flag)
        {
            flag=0;
            LED=RX_BUF[0];
        }            
    }
}
发送端程序
#include<reg52.h>
#include<api.h>
#define uint unsigned int
#define uchar unsigned char
#define LED P1
sbit key=P3^7;
//sbit beep=P2^5;
//sbit wela=P2^6;
//sbit dula=P2^7;
/***************************************************/
#define TX_ADR_WIDTH   5  // 5字节宽度的发送/接收地址
#define TX_PLOAD_WIDTH 4  // 数据通道有效数据宽度

uchar code TX_ADDRESS[TX_ADR_WIDTH] = {0x34,0x43,0x10,0x10,0x01};  // 定义一个静态发送地址
uchar RX_BUF[TX_PLOAD_WIDTH];
uchar TX_BUF[TX_PLOAD_WIDTH];
uchar flag;
uchar DATA = 0x01;
uchar bdata sta;
sbit  RX_DR     = sta^6;
sbit  TX_DS     = sta^5;
sbit  MAX_RT = sta^4;
/**************************************************
函数: init_io()

描述:
    初始化IO
/**************************************************/
void init_io(void)
{
   // dula=0;
   // wela=0;
    CE  = 0;        // 待机
    CSN = 1;        // SPI禁止
    SCK = 0;        // SPI时钟置低
    IRQ = 1;        // 中断复位
//    LED = 0xff;        // 关闭指示灯
}
/**************************************************
函数:delay()

描述:延时函数
**************************************************/
void delay(uint z)
{
    uint x;
    while(z--)
        for(x=110;x>0;x--);
}
/**************************************************
函数:SPI_RW()

描述:
    根据SPI协议,写一字节数据到nRF24L01,同时从nRF24L01
    读出一字节
/**************************************************/
uchar SPI_RW(uchar byte)
{
    uchar i;
    for(i=0;i<8;i++)
    {
        MOSI=(byte&0x80);
        byte<<=1;
        SCK=1;
        byte|=MISO;
        SCK=0;
    }
    return (byte);
}
/**************************************************
函数:SPI_RW_Reg()

描述:
    写数据value到reg寄存器
/**************************************************/
uchar SPI_RW_REG(uchar reg,uchar value)
{
    uchar status;
    CSN=0;
    status=SPI_RW(reg);
    SPI_RW(value);
    CSN=1;
    return(status);
}
/**************************************************
函数:SPI_Read()

描述:
    从reg寄存器读一字节
/**************************************************/
uchar SPI_READ(uchar reg)
{
    uchar status,reg_val;
    CSN=0;
    SPI_RW(reg);
    reg_val=SPI_RW(0);
    CSN=1;
    return(status);
}
/**************************************************
函数:SPI_Read_Buf()

描述:
    从reg寄存器读出bytes个字节,通常用来读取接收通道
    数据或接收/发送地址
/**************************************************/
uchar SPI_READ_BUF(uchar reg,uchar *pBUF,uchar byte)
{
    uchar status,i;
    CSN=0;
    status=SPI_RW(reg);
    for(i=0;i<byte;i++)
    {
        pBUF[i]=SPI_RW(0);
    }
    CSN=1;
    return(status);
}
/**************************************************
函数:SPI_Write_Buf()

描述:
    把pBuf缓存中的数据写入到nRF24L01,通常用来写入发
    射通道数据或接收/发送地址
/**************************************************/
uchar SPI_WRITE_BUF(uchar reg,uchar *pBUF,uchar byte)
{
    uchar status,i;
    CSN=0;
    status=SPI_RW(reg);
    for(i=0;i<byte;i++)
        SPI_RW(pBUF[i]);
    CSN=1;
    return(status);   
}
/**************************************************
函数:RX_Mode()

描述:
    这个函数设置nRF24L01为接收模式,等待接收发送设备的数据包
/**************************************************/
void RX_MODE()
{
    CE=0;
    SPI_WRITE_BUF(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH);
    SPI_RW_REG(WRITE_REG+EN_AA,0X01);
    SPI_RW_REG(WRITE_REG+EN_RXADDR,0X01);
    SPI_RW_REG(WRITE_REG+RF_CH,40);
    SPI_RW_REG(WRITE_REG+RX_PW_P0,TX_PLOAD_WIDTH);
    SPI_RW_REG(WRITE_REG+RF_SETUP,0X07);
    SPI_RW_REG(WRITE_REG+CONFIG,0x0f);
    CE=1;
}
/**************************************************
函数:TX_Mode()

描述:
    这个函数设置nRF24L01为发送模式,(CE=1持续至少10us),
    130us后启动发射,数据发送结束后,发送模块自动转入接收
    模式等待应答信号。
/**************************************************/
void TX_MODE(uchar *BUF)
{
    CE=0;
    SPI_WRITE_BUF(WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH);
    SPI_WRITE_BUF(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH);
    SPI_WRITE_BUF(WR_TX_PLOAD,BUF,TX_PLOAD_WIDTH);
    SPI_RW_REG(WRITE_REG+EN_AA,0X01);
    SPI_RW_REG(WRITE_REG+EN_RXADDR,0X01);
    SPI_RW_REG(WRITE_REG+SETUP_RETR,0X0A);
    SPI_RW_REG(WRITE_REG+RF_CH,40);
    SPI_RW_REG(WRITE_REG+RF_SETUP,0X07);
    SPI_RW_REG(WRITE_REG+CONFIG,0x0e);
    CE=1;
}
/**************************************************
函数:Check_ACK()

描述:
    检查接收设备有无接收到数据包,设定没有收到应答信
    号是否重发
/**************************************************/
uchar Check_ACK(bit clear)
{
    while(IRQ);
    sta = SPI_RW(NOP);                    // 返回状态寄存器
    if(MAX_RT)
        if(clear)                         // 是否清除TX FIFO,没有清除在复位MAX_RT中断标志后重发
            SPI_RW(FLUSH_TX);
    SPI_RW_REG(WRITE_REG + STATUS, sta);  // 清除TX_DS或MAX_RT中断标志
    IRQ = 1;
    if(TX_DS)
        return(0x00);
    else
        return(0xff);
}
/**************************************************
函数:keyscan()

描述:检测是否有按键按下,按下则发送一字节数据
**************************************************/
void keyscan()
{
    if(key==0)
    {
        delay(5);
        if(key==0)
        {
            TX_BUF[0]=~DATA;
            TX_MODE(TX_BUF);
            LED=~DATA;
            Check_ACK(1);
            delay(500);
            LED=0XFF;
            while(!key);
            DATA<<=1;
            if(!DATA)
                DATA=0x01;   
        }
    }
}
void main()
{
    init_io();
//    TX_MODE();
    while(1)
    {
        keyscan();   
    }
}

nRF24l01头文件
#ifndef _API_DEF_
#define _API_DEF_

// Define interface to nRF24L01

// Define SPI pins
sbit CE   = P1^0;  // Chip Enable pin signal (output)
sbit CSN  = P1^1;  // Slave Select pin, (output to CSN, nRF24L01)
sbit IRQ  = P1^3;  // Interrupt signal, from nRF24L01 (input)
sbit MISO = P1^4;  // Master In, Slave Out pin (input)
sbit MOSI = P1^5;  // Serial Clock pin, (output)
sbit SCK  = P1^7;  // Master Out, Slave In pin (output)

// SPI(nRF24L01) commands
#define READ_REG    0x00  // Define read command to register
#define 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)
#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

#endif   /* _API_DEF_ */

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