关于51单片机与nrf24l01的通讯问题

写了一个spi模拟通讯协议,想验证通信协议是否正确,身边就只找到了nrf24l01模块,费了九牛二虎之力撸完代码等待收获成功的喜悦,结果,status寄存器一直返回255,前面对nrf24l01一直没有研究,所以我不知道是spi时序问题还是nrf24l01的问题,下面是spi代码:

#include "SPI.h"
bit CPOL;
bit CPHA;
bit GD;

void Delay10us()        //@12MHz
{
    unsigned char i;

    _nop_();
    _nop_();
    i = 27;
    while (--i);
}

void SPI_init(unsigned char MS_1,bit MS_2){            //MS_1为模式选择(0,1,2,3),MS_2为高低位选择(0:低位在前,1:高位在前)
    switch(MS_1){
            case 0:
                CPOL = 0;
                CPHA = 0;
            break;
            case 1:
                CPOL = 0;
                CPHA = 1;
            break;
            case 2:
                CPOL = 1;
                CPHA = 0;
            break;
            case 3:
                CPOL = 1;
                CPHA = 1;
            break;
    }
    GD = MS_2;
    SCLK = CPOL;
//    CS = 1;
    MOSI = 1;
    MISO = 1;
}
unsigned char spi_RW(unsigned char spi_data){
    unsigned char tval=0x00,i;
//    CS = 0;
    for(i=0;i<8;i++)
    {
        if(CPHA)
        {
            Delay10us();
            SCLK = ~CPOL;
            if(GD)
                MOSI = 0x80&spi_data;
            else
                MOSI = 0x01&spi_data;
            Delay10us();
            Delay10us();
            SCLK = CPOL;
            if(GD)
            {
                tval <<= 1;
                if(MISO)
                    tval |= 0x01;
                spi_data <<= 1;
                
            }
            else
            {
                tval >>= 1;
                if(MISO)
                    tval |= 0x80;
                spi_data >>= 1;
                
            }
            Delay10us();
        }
        else
        {
            if(GD)
                MOSI = 0x80&spi_data;
            else
                MOSI = 0x01&spi_data;
            Delay10us();
            SCLK = ~CPOL;
            if(GD)
            {
                tval <<= 1;
                if(MISO)
                tval |= 0x01;
                spi_data <<= 1;
                
            }
            else
            {
                tval >>= 1;
                if(MISO)
                    tval |= 0x80;
                spi_data >>= 1;
                
            }
            Delay10us();
            Delay10us();
            SCLK = CPOL;
            Delay10us();
        }
    }
//  CS = 1;
    return tval;
}

上面片选信号在nrf24l01中实现,spi中未用到,下面是spi.h文件

#ifndef ___S____P___I___H__
#define ___S____P___I___H__
#include "STC.h"
#include 

sbit SCLK = P3^6;
sbit MOSI = P2^0;
sbit MISO = P2^2;
//sbit CS = P1^3;
void SPI_init(unsigned char MS_1,bit MS_2);           //MS_1为模式选择(0,1,2,3),MS_2为高低位选择(0:低位在前,1:高位在前)

unsigned char spi_RW(unsigned char spi_data);    //发送接收函数



#endif

nrf24l01程序有点长,

#include "nrf24l01.h"
unsigned char TX_addr1[]={0xc3,0xe4,0x6a,0xde,0xc6};
void NRF_init(){    //初始化工作
    SPI_init(0,1);  //SPI工作方式0,高位在前
    nrf_cs = 1;
    nrf_ce = 0;
}
unsigned char nrf_w_byte(unsigned char commd,unsigned char dat){ //写一个字节,带格式化地址
    unsigned char val1;
    commd &= 0x1f;
    commd |= 0x20;
    nrf_cs = 0;
    val1 = spi_RW(commd);
    spi_RW(dat);
    nrf_cs = 1;
    return val1;
}
unsigned char nrf_r_byte(unsigned char commd,unsigned char dat){ //读取一个字节  参数为地址,数据(一般是0xff)带地址格式化
    unsigned char val1;
    commd &= 0x1f;
    nrf_cs = 0;
    spi_RW(commd);
    val1 = spi_RW(dat);
    nrf_cs = 1;
    return val1;
}
unsigned char nrf_w_str(unsigned char commd,unsigned char *ndat,unsigned char nnum){//写入数组   参数为地址命令,数据数组,数据字节
    unsigned char i,val;
    nrf_cs = 0;
    val = spi_RW(commd); 
    for(i=0;i++){
        spi_RW(ndat[i]);
    }
    nrf_cs = 1;
    return val;
}
unsigned char nrf_r_str(unsigned char commd,unsigned char *ndat,unsigned char nnum){//读取数组,参数同上
    unsigned char i,val;
    nrf_cs = 0;
    val = spi_RW(commd); 
    for(i=0;i++){
        ndat[i] = spi_RW(0xff);
    }
    nrf_cs = 1;
    return val;
}
void NRF_send(unsigned char *dat,unsigned char snum){//准备作为写FIFO函数
    nrf_w_str(0xa0,dat,snum);
}
void NRF_accept(unsigned char *dat,unsigned char snum){//准备作为读FIFO函数
    nrf_w_str(0x61,dat,snum);
}
void NRF_clear(unsigned char mod_reg){ //FIFO寄存器清除操作参数mod_regT表示发送寄存器清0,R为接收寄存器清0
    switch(mod_reg){
        case 0:
            nrf_cs = 0;
            spi_RW(0xe1);
            spi_RW(0xff);
            nrf_cs = 1;
            break;
        case 1:
            nrf_cs = 0;
            spi_RW(0xe2);
            spi_RW(0xff);
            nrf_cs = 1;
            break;
    }
}
unsigned char NRF_status(){//读取状态寄存器
  return nrf_r_byte(0x07,0xff);//status
}
void NRF_TX_MODE(){//发送端设置,注释为对应寄存器名称
    nrf_w_byte(0x00,0x0a);//config
    nrf_w_byte(0x01,0x3f);//en_aa
    nrf_w_byte(0x02,0x01);//en_rx_addr
    nrf_w_byte(0x03,0x03);//setup_aw
    nrf_w_byte(0x04,0x0a);//setup_retr
    nrf_w_byte(0x05,0x3a);//rf_ch
    nrf_w_byte(0x06,0x0f);//config
    nrf_w_byte(0x07,0x0e);//status
    
    nrf_w_str(0x0a+0x20,TX_addr1,5);//rx_addr_p0
    nrf_w_str(0x10+0x20,TX_addr1,5);//tx_addr
    NRF_clear(0);
}


如上为所有代码,main函数只做了初始化并一直读取status寄存器数据,但是读取数据一直为0xff,为此我斥巨资35购入一台逻辑分析仪来观测数据时序,结果如图

img

img

img

观测到的mosi波形应该是正确的,但是nrf24l01一直返回0xff就让我非常迷茫

希望大家能指出是什么问题,怎么能正确收到status寄存器值

时钟线和片选线挂哪了???
C51的P0端口要外接上拉电阻,否则无法输出高电平,也就是说你的片选和时钟一直是低电平,芯片是无法正常通讯的,

255=0b11111111也就是说miso上一直是高电平,芯片没工作。

非常感谢大家,根据建议我突然想到既然时序没有问题那应该是电路问题,然后我用万用表测量了nrf24l01的引脚,差点气死,模块电源只有1v,然后在原理图上找3.3v电压哪来的,是不是芯片坏了,结果又气死,只有一个3.3v的标号,根本就没引出的脚,我TM…,严厉谴责普中这个开发版,太差劲了,浪费感情,还有个问题这个1v电压哪来的?