搜索
bottom↓
回复: 34

求助 nRF24L01 + 51单片机 测试程序 附源代码

[复制链接]

出0入0汤圆

发表于 2010-5-27 16:17:18 | 显示全部楼层 |阅读模式
麻烦各位专家赐教,
NRF24L01的实验程序调了一周了,还是不能通信,两天后就要,时间很紧,万请帮忙
用单片机是STC89LE58RD 3.3V的单片机
一端发送,一端接收
现在知道硬件肯定没问题
发送端和接收端的NRF24L01的寄存器已经正常读写,
发送端FIFO_STATUS在启动发送前后由不空变空,证明已经发送出去
但是接收端检测不到载波信号

附上源代码

出0入0汤圆

 楼主| 发表于 2010-5-27 16:17:46 | 显示全部楼层
/***以下为接收***/

#include <REGX52.H>
#include <INTRINS.H>                //for funtion _NOP_
#include <STDIO.H>

/***自定义数据类型声明***/
typedef unsigned char uchar;
typedef unsigned int uint;
/***宏定义***/
#define TRANSMIT_LED         1
#define RECEIVE_LED         0
#define LEDDATA                P0
#define SCAN_CYCLE        500                                                                //数码管动态扫描间隔
#define        TIMER1                0xe6                                                        //256-(110592/(12*32*96))
#define        TIMER0H                (65535-SCAN_CYCLE)/256
#define        TIMER0L                (65535-SCAN_CYCLE)%256                        //定时3MSVR3*FOSC/12/1000
/***I/O口定义***/
sbit MISO        =P1^6;
sbit MOSI        =P1^5;
sbit SCK        =P1^7;
sbit CE            =P1^3;
sbit CSN        =P1^4;
sbit IRQ        =P3^2;
sbit LED0        =P2^0;
sbit LED1        =P2^1;
/***显示及接收数据数组***/
code uchar TxBuf[32]=
{
        0x01,0x02,0x03,0x4,0x05,0x06,0x07,0x08,
        0x09,0x10,0x11,0x12,0x13,0x14,0x15,0x16,
        0x17,0x18,0x19,0x20,0x21,0x22,0x23,0x24,
        0x25,0x26,0x27,0x28,0x29,0x30,0x31,0x32,
};
code uchar RxBuf[32]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
uchar CheckBuf[32]=
{
        0x01,0x02,0x03,0x4,0x05,0x06,0x07,0x08,
        0x09,0x10,0x11,0x12,0x13,0x14,0x15,0x16,
        0x17,0x18,0x19,0x20,0x21,0x22,0x23,0x24,
        0x25,0x26,0x27,0x28,0x29,0x30,0x31,0x32,
};
uchar dis_buf[2]={0x00,0x00};        //显示数组
code uchar LED7Code[]={
        0xC0,                // 0
        0xF9,                // 1
        0xA4,                // 2
        0xB0,                // 3
        0x99,                // 4
        0x92,                // 5
        0x82,                // 6
        0xF8,                // 7
        0x80,                // 8
        0x90,                // 9
        0x88,                // A
        0x83,                // B
        0xC6,                // C
        0xA1,                // D
        0x86,                // E
        0x8E,                // F
        0xFF,                //熄灭
};

/***NRF24L01***/
#define TX_ADR_WIDTH    5           // 5 uints TX address width
#define RX_ADR_WIDTH    5           // 5 uints RX address width
#define TX_PLOAD_WIDTH  32         // 32 uints TX payload
#define RX_PLOAD_WIDTH  32          // 32 uints TX payload
uchar const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};        //本地地址
uchar const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};        //接收地址
/***NRF24L01寄存器指令***/
#define READ_REG        0x00          // 读寄存器指令
#define WRITE_REG       0x20         // 写寄存器指令
#define RD_RX_PLOAD     0x61          // 读取接收数据指令
#define WR_TX_PLOAD     0xA0          // 写待发数据指令
#define FLUSH_TX        0xE1         // 冲洗发送 FIFO指令
#define FLUSH_RX        0xE2          // 冲洗接收 FIFO指令
#define REUSE_TX_PL     0xE3          // 定义重复装载数据指令
#define NOP             0xFF          // 保留
/***SPI(nRF24L01)寄存器地址***/
#define CONFIG          0x00  // 配置收发状态,CRC校验模式以及收发状态响应方式
#define EN_AA           0x01  // 自动应答功能设置
#define EN_RXADDR       0x02  // 可用信道设置
#define SETUP_AW        0x03  // 收发地址宽度设置 11 0x03 5bytes
#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  // 接收频道0接收数据长度
#define RX_PW_P2        0x13  // 接收频道0接收数据长度
#define RX_PW_P3        0x14  // 接收频道0接收数据长度
#define RX_PW_P4        0x15  // 接收频道0接收数据长度
#define RX_PW_P5        0x16  // 接收频道0接收数据长度
#define FIFO_STATUS     0x17  // FIFO栈入栈出状态寄存器设置
/***NRF24L01状态标志***/
uint         bdata sta;   //状态标志
sbit        RX_DR        =sta^6;
sbit        TX_DS        =sta^5;
sbit        MAX_RT        =sta^4;
uchar        flag;

/***函数声明***/
void Delayms(uint s);       
void Delayus(uchar n);
void InitTimer(void);
void InitUART(void);
void InitNRF24L01(void);               
void SetRXMode(void);

uchar SPI_RW(uchar); //NRF24L01的SPI写时序;写一个字节到24l01,同时读出一个字节
uchar SPI_Read(uchar reg);        //NRF24L01的SPI读时序                       
uchar SPI_Read_Reg(uchar reg);//从寄存器reg读一个字节               
uchar SPI_RW_Reg(uchar reg, uchar value);//向寄存器reg写一个字节,同时返回状态字节

uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar bytes); //从寄存器reg读出bytes个字节,通常用来读取接收通道数据或发送地址
uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes);//把pBuf缓存中的数据写入到nRF24L01,通常用来写入发射通道数据或接收/发送地址

uchar nRF24L01_RxPacket(uchar *rx_buf);                //接收函数,返回1收到,
void nRF24L01_TxPacket(uchar *tx_buf);                //发送函数

/**********************************************************************
函数:void Delay(uint s)
描述:
**********************************************************************/
void Delayms(uint s)
{
        unsigned int i,j;
        for(i=0; i<s; i++);
        for(j=0; j<12; j++);
}
/**********************************************************************
函数:void Delayus(uchar n)
描述:短延时函数,延时9n+4 us
**********************************************************************/
void Delayus(uchar n)
{                                               
        for(;n>0;n--)
                _nop_();
}

/*****************************************************************************************
函数:void InitTimer(void)
描述:定时器0初始化程序
*****************************************************************************************/
void InitTimer(void)
{
        TMOD = 0x21;                //定时器1工作方式2,定时器0工作方式1
        TH0 = TIMER0H;                //设定T0每隔SCAN_CYCLE us中断一次
        TL0 = TIMER0L;
        IE=0x82;                        //|EA|-|ET2|ES|ET1|EX1|ET0|EX0|
        //ET0 = 1;                        //定时器0中断允许
        //EA = 1;                                //开全局中断
        TF0 = 0;                        //中断标志重置
        TR0 = 1;                        //启动定时器0
}

/*****************************************************************************************
函数:void InitUART(void)
描述:串口初始化程序
*****************************************************************************************/
void InitUART(void)                //波特率9600
{

        SCON = 0x50;                //串口方式1,允许接收
//        TI=1;
        TH1 = TIMER1;       
        TL1 = TIMER1;
        PCON = 0x00;       
        TR1 = 1;                //启动定时器1
}
/****************************************************************************************
函数:void InitNRF24L01(void)
描述:NRF24L01初始化
****************************************************************************************/
void InitNRF24L01(void)
{
        Delayus(100);
        CE  = 0;        // 待机
        CSN = 1;        // SPI禁止
        SCK = 0;        // SPI时钟置低
        IRQ = 1;        // 中断复位
}

/**************************************************
函数:SetRXMode()
描述:设置nRF24L01为接收模式,等待接收发送设备的数据包
**************************************************/
void SetRXMode(void)
{
        CE = 0;                        //Standby-1
          SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);  // 写本地地址
        SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH);  // 接收设备接收通道0使用和发送设备相同的发送地址
          SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);           // 使能接收通道0
          SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);               // 使能接收通道0自动应答
          SPI_RW_Reg(WRITE_REG + RF_CH, 0x00);               // 选择射频通道0x00
          SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH);  // 接收通道0选择和发送通道相同有效数据宽度
          SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);            // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益
    SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);              // CRC使能,16位CRC校验,上电,接收模式
          CE = 1;                                            // 拉高CE启动接收设备
        Delayus(130);                                                                           // Standby-1 to RXMode need 130us
}
/******************************************************************************************************
函数:uchar nRF24L01_RxPacket(uchar *rx_buf)
描述:数据读取后放入rx_buf接收缓冲区中
******************************************************************************************************/
uchar nRF24L01_RxPacket(uchar *rx_buf)
{
    uchar revale=0;
        sta=SPI_Read_Reg(STATUS);        // 读取状态寄存其来判断数据接收状况
        if(RX_DR)                                // 判断是否接收到数据
        {
            CE = 0;                         //Stand by
                SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// read receive payload from RX_FIFO buffer
                revale =1;                        //读取数据完成标志
        }
        SPI_RW_Reg(WRITE_REG+STATUS,sta);   //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清除中断标志
        return revale;
}


/****************************************************************************************************
函数:uint SPI_RW(uint uchar)
描述:NRF24L01的SPI写时序
/****************************************************************************************************/
uchar SPI_RW(uchar uch)
{
        uint bit_ctr;
           for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
           {
                MOSI = (uch & 0x80);         // output 'uchar', MSB to MOSI
                uch = (uch << 1);           // shift next bit into MSB..
                SCK = 1;                      // Set SCK high..
                uch |= MISO;                         // capture current MISO bit
                SCK = 0;                              // ..then set SCK low again
           }
    return(uch);                             // return read uchar
}
/****************************************************************************************************
/*函数:uchar SPI_Read(uchar reg)
/*功能:NRF24L01的SPI读时序
/****************************************************************************************************/
uchar SPI_Read_Reg(uchar reg)
{
        uchar reg_val;
       
        CSN = 0;                // CSN low, initialize SPI communication...
        SPI_RW(reg);            // Select register to read from..
        reg_val = SPI_RW(0);    // ..then read registervalue
        CSN = 1;                // CSN high, terminate SPI communication
       
        return(reg_val);        // return register value
}

/****************************************************************************************************
函数:uint SPI_RW_Reg(uchar reg, uchar value)
描述:NRF24L01读写寄存器函数
****************************************************************************************************/
uchar SPI_RW_Reg(uchar reg, uchar value)
{
        uchar status;
       
        CSN = 0;                   // CSN low, init SPI transaction
        status = SPI_RW(reg);      // select register
        SPI_RW(value);             // ..and write value to it..
        CSN = 1;                   // CSN high again
       
        return(status);            // return nRF24L01 status uchar
}
/****************************************************************************************************
函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar bytes)
功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,bytes:读出数据的个数
****************************************************************************************************/
uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar bytes)
{
        uint status,uchar_ctr;
       
        CSN = 0;                                    // Set CSN low, init SPI tranaction
        status = SPI_RW(reg);                       // Select register to write to and read status uchar
       
        for(uchar_ctr=0;uchar_ctr<bytes;uchar_ctr++)
                pBuf[uchar_ctr] = SPI_RW(0);    //
       
        CSN = 1;                           
       
        return(status);                    // return nRF24L01 status uchar
}
/*****************************************************************************************************
函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes)
功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,bytes:写入数据的个数
*****************************************************************************************************/
uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes)
{
        uchar status,uchar_ctr;
       
        CSN = 0;            //SPI使能      
        status = SPI_RW(reg);   
        for(uchar_ctr=0; uchar_ctr<bytes; uchar_ctr++) //
                SPI_RW(*pBuf++);
        CSN = 1;           //关闭SPI
        return(status);    //
}


/************************************************************************
函数:void ScanSeg7()
描述:数码管扫描显示
************************************************************************/
void ScanSeg7()                             //数码管扫描显示,一次扫描一位数码管
{
    static uchar scanCounter=0;
        LED1=1;
        LED0=1;
    if(scanCounter==RECEIVE_LED)
        {
                LEDDATA=dis_buf[RECEIVE_LED];
                LED0=0;
                scanCounter=TRANSMIT_LED;
        }
        else                                   //scanCounter=TRANSMIT_LED
        {
            LEDDATA=dis_buf[TRANSMIT_LED];
            LED1=0;
            scanCounter=RECEIVE_LED;
        }
}
/************************************************************************
函数:void Timer0_OverFlow()  interrupt 1
描述:Timer0溢出中断,用于数码管动态扫描定时
************************************************************************/
void Timer0_OverFlow()  interrupt 1 //500us中断一次
{       
       
        ScanSeg7();        //扫描数码管
        TH0=(65536-SCAN_CYCLE)/256; //设定Timer0每隔SCAN_CYCLE us中断一次
    TL0=(65536-SCAN_CYCLE)%256;
        TF0=0;                  //定时器0中断标志位清零
       
}
/*****************************************************
函数:bit ErrorCheck(void)
描述:错误校验程序,检查收到的数据包是否正确
*****************************************************/
uchar ErrorCheck(void)
{
        uchar i;
        for(i=0;i<32;i++)
        {
                if(RxBuf!=TxBuf)
                return 1;
        }
        return 0;
}
/************************************************************************
函数:void R_S_Byte(uchar R_Byte)
描述:通过串口将接收到数据发送给PC端
************************************************************************/
void R_S_Byte(uchar R_Byte)
{       
         SBUF = R_Byte;  
     while( TI == 0 );                                //查询法
           TI = 0;   
}
/************************************************************************
函数:void main(void)
描述:主函数
************************************************************************/
void main(void)
{
        int i;
        uchar rabuf[5]={0};
        uchar tabuf[5]={0};
        InitTimer();        //Timer初始化
        InitUART();                //串口初始化
    InitNRF24L01();        //24l01初始化

    LED0=1;
        LED1=1;
        //dis_buf[0]=LED7Code[13];
        //dis_buf[1]=LED7Code[13];
        //while(1);
        SetRXMode();        //进入接收模式
       
/*        TI=1;
        printf("CONFIG=0x%x\n",(int)SPI_Read_Reg(CONFIG));
        printf("EN_AA=0x%x\n",(int)SPI_Read_Reg(EN_AA));
        printf("EN_RXADDR=0x%x\n",(int)SPI_Read_Reg(EN_RXADDR));
        printf("SETUP_AW=0x%x\n",(int)SPI_Read_Reg(SETUP_AW));
        printf("SETUP_RETR=0x%x\n",(int)SPI_Read_Reg(SETUP_RETR));
        printf("RF_CH=0x%x\n",(int)SPI_Read_Reg(RF_CH));
        printf("RF_SETUP=0x%x\n",(int)SPI_Read_Reg(RF_SETUP));
        printf("STATUS=0x%x\n",(int)SPI_Read_Reg(STATUS));
        printf("OBSERVE_TX=0x%x\n",(int)SPI_Read_Reg(OBSERVE_TX));
        printf("CD=0x%x\n",(int)SPI_Read_Reg(CD));
        printf("FIFO_STATUS=0x%x\n",(int)SPI_Read_Reg(FIFO_STATUS));
        SPI_Read_Buf(TX_ADDR,tabuf,5);
        for(i=0;i<5;i++)
        printf("tabuf[%d]=0x%x\n",i,(int)tabuf);
        SPI_Read_Buf(RX_ADDR_P0,rabuf,5);
        for(i=0;i<5;i++)
        printf("rabuf[%d]=0x%x\n",i,(int)rabuf);
        SPI_RW(FLUSH_RX);
        SPI_RW(FLUSH_TX);
        Delayus(2);
*/
        do
        {
                //if(RX_DR)
                //printf("%s\n","rs");
                nRF24L01_RxPacket(RxBuf);
                //SPI_Read_Buf(RD_RX_PLOAD,RxBuf,TX_PLOAD_WIDTH);
//                if(nRF24L01_RxPacket(RxBuf))
//                printf("DataReceived\n");
//                printf("CD=0x%x\n",(int)SPI_Read_Reg(CD));
                for(i=0;i<32;i++)
                printf("RxBuf[%d]=0x%x\n",i,(int)RxBuf);
        if(ErrorCheck())
                {
                        dis_buf[0]=LED7Code[15];
                        dis_buf[1]=LED7Code[15];
                }
                else
                {
                        dis_buf[0]=LED7Code[10];
                        dis_buf[1]=LED7Code[10];
                }
        }
        while(IRQ == 0);
        //dis_buf[0]=LED7Code[14];
        //dis_buf[1]=LED7Code[14];
        //        while(IRQ==0)        //发送完毕,
        //        R_S_Byte(&RxBuf[0]);
//        while(1)       
//        printf("CD=0x%x",(int)SPI_Read_Reg(CD));
}

/*        if(nRF24L01_RxPacket(RxBuf))
                {
                        for(i=0;i<32;i++)
                        {
                                R_S_Byte(RxBuf);
                                Delayms(600);
                        }       
                }
*/

/*
        while(1)
        {
                sta = SPI_Read(STATUS);          // 读状态寄存器
            if(RX_DR)                                  // 判断是否接受到数据
                {
                        SPI_Read_Buf(RD_RX_PLOAD, RxBuf, TX_PLOAD_WIDTH);  // 从RX FIFO读出数据
                        flag = 1;
                }
                SPI_RW_Reg(WRITE_REG + STATUS, sta);  // 清除RX_DS中断标志
                if(flag)                           // 接受完成
                {
                        flag = 0;                       // 清标志
                        LED = RxBuf[0];           // 数据送到LED显示
                        Delayms(250);
                        Delayms(250);
                          LED = 0xff;                       // 关闭LED
                }
        }
*/




/*                   if(nRF24L01_RxPacket(RxBuf))
                {
                        temp++;
                        for(i=0;i<32;i++)
                        {
                                R_S_Byte(RxBuf);
                                Delay(600);
                        }       
                }
*/

出0入0汤圆

 楼主| 发表于 2010-5-27 16:18:50 | 显示全部楼层
/***以下为发送***/


#include <reg52.h>
#include <intrins.h>
#include <stdio.h>

typedef unsigned char uchar;
typedef unsigned char uint;
//****************************************IO端口定义***************************************
#define TRANSMIT_LED 1
#define RECEIVE_LED 0
#define LEDDATA P0
#define SCAN_CYCLE 500
#define        TIMER0H                (65535-SCAN_CYCLE)/256
#define        TIMER0L                (65535-SCAN_CYCLE)%256                        //定时3MSVR3*FOSC/12/1000
uchar dis_buf[2]={0x00,0x00};        //显示数组
sbit         MISO        =P1^6;
sbit         MOSI        =P1^5;
sbit        SCK            =P1^7;
sbit        CE            =P1^3;
sbit        CSN                =P1^4;
sbit        IRQ                =P3^2;
//***********************************数码管0-F编码*******************************************
const unsigned char LED7Code[]={
        0xC0,                // 0
        0xF9,                // 1
        0xA4,                // 2
        0xB0,                // 3
        0x99,                // 4
        0x92,                // 5
        0x82,                // 6
        0xF8,                // 7
        0x80,                // 8
        0x90,                // 9
        0x88,                // A
        0x83,                // B
        0xC6,                // C
        0xA1,                // D
        0x86,                // E
        0x8E,                // F
        0xFF,                //熄灭
};      
code uchar TxBuf[32]=
{
        0x01,0x02,0x03,0x4,0x05,0x06,0x07,0x08,
        0x09,0x10,0x11,0x12,0x13,0x14,0x15,0x16,
        0x17,0x18,0x19,0x20,0x21,0x22,0x23,0x24,
        0x25,0x26,0x27,0x28,0x29,0x30,0x31,0x32,
};         //
//***********************************数码管位选**************************************************
sbit        LED1=P2^1;
sbit        LED0=P2^0;
//*********************************************NRF24L01*************************************
#define TX_ADR_WIDTH    5           // 5 uints TX address width
#define RX_ADR_WIDTH    5           // 5 uints RX address width
#define TX_PLOAD_WIDTH  32          // 20 uints TX payload
#define RX_PLOAD_WIDTH  32          // 20 uints TX payload
uint const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};        //本地地址
uint const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};        //接收地址
//***************************************NRF24L01寄存器指令*******************************************************
#define READ_REG        0x00          // 读寄存器指令
#define WRITE_REG       0x20         // 写寄存器指令
#define RD_RX_PLOAD     0x61          // 读取接收数据指令
#define WR_TX_PLOAD     0xA0          // 写待发数据指令
#define FLUSH_TX        0xE1         // 冲洗发送 FIFO指令
#define FLUSH_RX        0xE2          // 冲洗接收 FIFO指令
#define REUSE_TX_PL     0xE3          // 定义重复装载数据指令
#define NOP             0xFF          // 保留
//*************************************SPI(nRF24L01)寄存器地址****************************************************
#define CONFIG          0x00  // 配置收发状态,CRC校验模式以及收发状态响应方式
#define EN_AA           0x01  // 自动应答功能设置
#define EN_RXADDR       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  // 接收频道0接收数据长度
#define RX_PW_P2        0x13  // 接收频道0接收数据长度
#define RX_PW_P3        0x14  // 接收频道0接收数据长度
#define RX_PW_P4        0x15  // 接收频道0接收数据长度
#define RX_PW_P5        0x16  // 接收频道0接收数据长度
#define FIFO_STATUS     0x17  // FIFO栈入栈出状态寄存器设置
//**************************************************************************************
void Delay(unsigned int s);
void inerDelay_us(unsigned char n);
void init_NRF24L01(void);
uchar SPI_RW(uchar uch);
uchar SPI_Read_Reg(uchar reg);
void SetRX_Mode(void);
uchar SPI_RW_Reg(uchar reg, uchar value);
uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);
uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);
uchar nRF24L01_RxPacket(unsigned char* rx_buf);
void nRF24L01_TxPacket(unsigned char * tx_buf);
//*****************************************长延时*****************************************
void Delay(unsigned int s)
{
        unsigned int i;
        for(i=0; i<s; i++);
        for(i=0; i<s; i++);
}
//******************************************************************************************
uint         bdata sta;   //状态标志
sbit        RX_DR        =sta^6;
sbit        TX_DS        =sta^5;
sbit        MAX_RT        =sta^4;
/******************************************************************************************
/*延时函数
/******************************************************************************************/
void inerDelay_us(unsigned char n)
{
        for(;n>0;n--)
                _nop_();
}

/*****************************************************************************************
函数:void InitTimer(void)
描述:定时器0初始化程序
*****************************************************************************************/
void InitTimer(void)
{
        TMOD = 0x21;                //定时器1工作方式2,定时器0工作方式1
        TH0 = TIMER0H;                //设定T0每隔SCAN_CYCLE us中断一次
        TL0 = TIMER0L;
        IE=0x82;                        //|EA|-|ET2|ES|ET1|EX1|ET0|EX0|       
        //ET0 = 1;                        //定时器0中断允许
        //EA = 1;                                //开全局中断
        TF0 = 0;                        //中断标志重置
        TR0 = 1;                        //启动定时器0
}

/*****************************************************************************************
函数:void InitUART(void)
描述:串口初始化程序
*****************************************************************************************/
void InitUART(void)                //波特率9600
{

        SCON = 0x50;                //串口方式1,允许接收
        TI=1;
//        TH1 = 0xe5;                //12 The byte rate is 1200
//        TL1 = 0xe5;
        TH1 = 0xe8;                //11.0592 The byte rate is 1200
        TL1 = 0xe8;
        PCON = 0x00;       
        TR1 = 1;                //启动定时器1
}
//****************************************************************************************
/*NRF24L01初始化
//***************************************************************************************/
void init_NRF24L01(void)
{
    inerDelay_us(100);
        CE=0;    // chip enable
        CSN=1;   // Spi disable
        SCK=0;   // Spi clock line init low
        IRQ = 1;        // 中断复位

}
/****************************************************************************************************
/*函数:uint SPI_RW(uint uchar)
/*功能:NRF24L01的SPI写读时序
/****************************************************************************************************/
uchar SPI_RW(uchar uch)
{
        uchar bit_ctr;
           for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
           {
                MOSI = (uch & 0x80);         // output 'uchar', MSB to MOSI
                uch = (uch << 1);         // shift next bit into MSB..
                SCK = 1;                      // Set SCK high..
                uch |= MISO;                         // capture current MISO bit
                SCK = 0;                              // ..then set SCK low again
           }
    return(uch);                             // return read uchar
}
/****************************************************************************************************
/*函数:uchar SPI_Read(uchar reg)
/*功能:读NRF24L01的寄存器
/****************************************************************************************************/
uchar SPI_Read_Reg(uchar reg)
{
        uchar reg_val;
       
        CSN = 0;                // CSN low, initialize SPI communication...
        SPI_RW(reg);            // Select register to read from..
        reg_val = SPI_RW(0);    // ..then read registervalue
        CSN = 1;                // CSN high, terminate SPI communication
       
        return(reg_val);        // return register value
}
/****************************************************************************************************/
/*功能:NRF24L01写寄存器函数
/****************************************************************************************************/
uchar SPI_RW_Reg(uchar reg, uchar value)
{
        uchar status;
       
        CSN = 0;                   // CSN low, init SPI transaction
        status = SPI_RW(reg);      // select register
        SPI_RW(value);             // ..and write value to it..
        CSN = 1;                   // CSN high again
       
        return(status);            // return nRF24L01 status uchar
}
/****************************************************************************************************/
/*函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
/*功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数
/****************************************************************************************************/
uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
{
        uchar status,uchar_ctr;
       
        CSN = 0;                                    // Set CSN low, init SPI tranaction
        status = SPI_RW(reg);                       // Select register to write to and read status uchar
       
        for(uchar_ctr=0;uchar_ctr<uchars;uchar_ctr++)
                pBuf[uchar_ctr] = SPI_RW(0);    //
       
        CSN = 1;                           
       
        return(status);                    // return nRF24L01 status uchar
}
/*********************************************************************************************************
/*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
/*功能: 用于写数据:reg为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数
/*********************************************************************************************************/
uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
{
        uchar status,uchar_ctr;
       
        CSN = 0;            //SPI使能      
        status = SPI_RW(reg);   
        for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr++) //
                SPI_RW(*pBuf++);
        CSN = 1;           //关闭SPI
        return(status);    //
}
/****************************************************************************************************/
/*函数:void SetTxMode(void)
/*功能:数据发送配置
/****************************************************************************************************/
void SetTxMode(void)
{
        CE=0;
        SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    // 写本地地址       
        SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址
        //SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);      //  频道0自动        ACK应答允许
        SPI_RW_Reg(WRITE_REG + EN_AA, 0x00);       
        SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  //  允许接收地址只有频道0,如果需要多频道可以参考Page21  
          //SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 500us + 86us, 10 retrans...       
        SPI_RW_Reg(WRITE_REG + RF_CH, 0x00);        //   设置信道工作为2.4GHZ,收发必须一致
        SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
        SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);                   //设置发射速率为1MHZ,发射功率为最大值0dB       
        SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);                    // IRQ收发完成中断响应,16位CRC,主发送
        SPI_RW_Reg(WRITE_REG + STATUS, 0x7e);                         //写状态寄存器
       
}
/****************************************************************************************************/
/*函数:void SetRX_Mode(void)
/*功能:数据接收配置
/****************************************************************************************************/
void SetRX_Mode(void)
{
        CE=0;
        SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);                   // IRQ收发完成中断响应,16位CRC        ,主接收
        CE = 1;
        inerDelay_us(130);
}

/******************************************************************************************************/
/*函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
/*功能:数据读取后放在rx_buf接收缓冲区中
/******************************************************************************************************/
uchar nRF24L01_RxPacket(unsigned char* rx_buf)
{
    unsigned char revale=0;
        sta=SPI_Read_Reg(STATUS);        // 读取状态寄存其来判断数据接收状况
        if(RX_DR)                                // 判断是否接收到数据
        {
            CE = 0;                         //SPI使能
                SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// read receive payload from RX_FIFO buffer
                revale =1;                        //读取数据完成标志
        }
        SPI_RW_Reg(WRITE_REG+STATUS,sta);   //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志
        return revale;
}
/***********************************************************************************************************
/*函数:void nRF24L01_TxPacket(unsigned char * tx_buf)
/*功能:发送 tx_buf中数据
/**********************************************************************************************************/
void nRF24L01_TxPacket(unsigned char * tx_buf)
{
        int i;
        //CE=0;                        //StandBy I模式       
        SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);
        SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址
        SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH);                          // 装载数据
        printf("Load data\n");
        printf("FIFO_STATUS=0x%x\n",(int)SPI_Read_Reg(FIFO_STATUS));
        SPI_Read_Buf(WR_TX_PLOAD,TxBuf,TX_PLOAD_WIDTH);
        for(i=0;i<32;i++)
        {
        printf("TxBuf[%d]=0x%x\n",i,(int)TxBuf);
        }
//        SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);                    // IRQ收发完成中断响应,16位CRC,主发送
//        SPI_RW(REUSE_TX_PL);
        CE=1;                 //置高CE,激发数据发送
        inerDelay_us(10);
        inerDelay_us(130);

}
//************************************************************************************************
void ScanSeg7()                             //数码管扫描显示,一次扫描一位数码管
{
    static uchar scanCounter=0;
        LED1=1;
        LED0=1;
    if(scanCounter==RECEIVE_LED)
        {
                LEDDATA=dis_buf[RECEIVE_LED];
                LED0=0;
                scanCounter=TRANSMIT_LED;
        }else //scanCounter=TRANSMIT_LED
        {
            LEDDATA=dis_buf[TRANSMIT_LED];
            LED1=0;
            scanCounter=RECEIVE_LED;
        }
}
//*********************************************************************************************************
void Timer0_OverFlow()  interrupt 1 //500us中断一次
{       
       
        ScanSeg7();        //扫描数码管
        TH0=(65536-SCAN_CYCLE)/256; //设定Timer0每隔SCAN_CYCLE us中断一次
    TL0=(65536-SCAN_CYCLE)%256;
        //TF0=0;                  //定时器0中断标志位清零
       
}
/********************************
check_ACK();
********************************/
void check_ACK()
{
        uchar test;
        test=SPI_Read_Reg(READ_REG+STATUS);        // read register STATUS's
        test=test&0x20;                                        // check if have Data sent TX FIFO interrupt (TX_DS=1)
        if(test==0x20)                                        // TX_DS =1
        {
                P0=0x00;                                        // turn on all led
            Delay(100);                                        // delay 100ms
                P0=0xff;
        }
}
//************************************主函数************************************************************
void main(void)
{
        uchar tabuf[5]={0};
        uchar rabuf[5]={0};
        int i ;

        InitTimer();        //Timer初始化
        InitUART();                //串口初始化       
    init_NRF24L01();
        SetTxMode();
       
        Delay(1000);
        printf("CONFIG=0x%x\n",(int)SPI_Read_Reg(CONFIG));
        printf("EN_AA=0x%x\n",(int)SPI_Read_Reg(EN_AA));
        printf("EN_RXADDR=0x%x\n",(int)SPI_Read_Reg(EN_RXADDR));
        printf("SETUP_AW=0x%x\n",(int)SPI_Read_Reg(SETUP_AW));
        printf("SETUP_RETR=0x%x\n",(int)SPI_Read_Reg(SETUP_RETR));
        printf("RF_CH=0x%x\n",(int)SPI_Read_Reg(RF_CH));
        printf("RF_SETUP=0x%x\n",(int)SPI_Read_Reg(RF_SETUP));
        printf("STATUS=0x%x\n",(int)SPI_Read_Reg(STATUS));
        printf("OBSERVE_TX=0x%x\n",(int)SPI_Read_Reg(OBSERVE_TX));
        printf("CD=0x%x\n",(int)SPI_Read_Reg(CD));
        printf("TX_ADDR=0x%x\n",(int)SPI_Read_Reg(TX_ADDR));
        SPI_Read_Buf(TX_ADDR,tabuf,TX_ADR_WIDTH);
        for(i=0;i<5;i++){
                printf("tabuf[%d]=0x%x\n",i,(int)tabuf);
        }
        SPI_Read_Buf(RX_ADDR_P0,rabuf,TX_ADR_WIDTH);
        for(i=0;i<5;i++){
                printf("rabuf[%d]=0x%x\n",i,(int)rabuf);
        }
       
        LED0=0;
        LED1=0;
        P0=0x00;
        dis_buf[0]=LED7Code[10];
        dis_buf[1]=LED7Code[10];
        printf("SetTxMode\n");
        printf("FIFO_STATUS=0x%x\n",(int)SPI_Read_Reg(FIFO_STATUS));
        while(1)
        {       
               
                printf("Enter while(1)\n");
               
                 do
                {
        //                printf("IRQ==0\n");
                        nRF24L01_TxPacket(TxBuf);        // Transmit Tx buffer data
                        printf("transmit\n");
                        printf("FIFO_STATUS=0x%x\n",(int)SPI_Read_Reg(FIFO_STATUS));
                        SPI_Read_Buf(WR_TX_PLOAD,TxBuf,TX_PLOAD_WIDTH);
                        for(i=0;i<32;i++)
                        {
                         printf("TxBuf[%d]=0x%x\n",i,(int)TxBuf);
                        }
                //        check_ACK();
                        Delay(6000);
                //        printf("Transmit\n");
                       
                }while(IRQ==0);
                while(IRQ!=0)
                {
                        printf("IRQ!=0\n");
                        printf("FIFO_STATUS=0x%x\n",(int)SPI_Read_Reg(FIFO_STATUS));
                };
               
        }

}

出0入0汤圆

发表于 2010-5-28 10:56:06 | 显示全部楼层
你买的哪家的东西?
直接找他们技术支持啊

出0入0汤圆

发表于 2010-5-29 18:31:53 | 显示全部楼层
方便留个联系方式么, profcole,我也正在玩这个无线,交流,交流,我的QQ:512582511

出0入0汤圆

发表于 2010-6-2 22:22:57 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-6-2 23:42:32 | 显示全部楼层
学习了

出0入0汤圆

发表于 2010-7-29 20:49:43 | 显示全部楼层
mark thanks

出0入0汤圆

发表于 2010-7-30 08:29:02 | 显示全部楼层
加我吧。看你们这么辛苦

出0入0汤圆

发表于 2010-8-9 17:03:49 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-8-10 14:46:52 | 显示全部楼层
哇,真厉害啊

出0入0汤圆

发表于 2010-9-8 11:27:11 | 显示全部楼层
楼主自己写的吗

出0入0汤圆

发表于 2010-9-8 12:03:02 | 显示全部楼层
点击此处下载 ourdev_581189UYLUE2.pdf(文件大小:300K) (原文件名:Moreway-RF24L01.pdf)
点击此处下载 ourdev_581190YR3W9F.rar(文件大小:58K) (原文件名:Moreway1000_NRF24L01.rar)

出0入0汤圆

发表于 2010-10-7 20:20:23 | 显示全部楼层
MARK

出0入0汤圆

发表于 2010-10-21 16:03:27 | 显示全部楼层
标记

出0入0汤圆

发表于 2010-11-2 16:55:16 | 显示全部楼层
我也在做,程序烦啊。。。。

出0入0汤圆

发表于 2011-3-21 19:39:14 | 显示全部楼层
ding qi

出0入0汤圆

发表于 2011-4-12 22:00:02 | 显示全部楼层
我也玩24L01了 需要仿真机么…… 直接用AT89S52控制的人飘过。。。

出0入0汤圆

发表于 2011-4-27 22:08:54 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-4-27 23:46:59 | 显示全部楼层
NRF24L01/NRF24L01+
无线不在神秘 零难度入门
买回就可以看到通信效果
第一次应用和初学者不在为无线迷茫
感性认识+理性分析-->轻松驾驭NRF24L01+
NRF24L01/NRF24L01+是挪威NordicVLSI公司出品的一款新型射频收发器件,采用4 mm×4 mmQFN20封装;NRF24L01/NRF24L01+工作在ISM频段:2.4~2.524 GHz。且内置频率合成器、功率放大器、晶体振荡器、调制器等功能,并融合增强型ShockBurst技术,其中地址、输出功率和通信频道可通过程序进行配置,适合用于多机通信。NRF24L01/NRF24L01+功耗很低,在以-6 dBm的功率发射时,工作电流也只有9 mA;而对应接收机的工作电流只有12.3 mA,多种低功率工作模式(掉电模式和空闲模式)使节能设计更方便。NRF24L01/NRF24L01+在业界领先的低功耗特点使其特别适合采用钮扣电池供电的2.4G应用,整个解决方案包括链路层和MultiCeiver功能提供了比现有的nRF24XX更多的功能和更低的电源消耗,与目前的蓝牙技术相比在提供更高速率的同时,而只需花更小的功耗.最新采用的nRF24L01+与nRF24L01兼容,并增加250kbps低速功能。
详细点连接:http://item.taobao.com/item.htm?id=10096264698
让我们想的更多,做的更到位,你的无线应用更轻松,更简单


点击此处下载 ourdev_632805VFO9Y3.pdf(文件大小:1.49M) (原文件名:JASK51-24L01模块使用手册.pdf)
点击此处下载 ourdev_632806C18V47.pdf(文件大小:1.56M) (原文件名:USB-TTL模块使用手册.pdf)


点击此处下载 ourdev_632781Z4RW87.pdf(文件大小:462K) (原文件名:nRF24L01芯片文档.pdf)
点击此处下载 ourdev_632782PCXG7E.pdf(文件大小:1.08M) (原文件名:nRF24L01+.pdf)


(原文件名:DSC02404.JPG)

出0入0汤圆

发表于 2011-5-11 17:00:33 | 显示全部楼层
好东西,标记下!

出0入0汤圆

发表于 2011-5-15 10:08:20 | 显示全部楼层
2.4g这个东西时需要慢慢一点一点调试的,第一次我调试两天出来效果了,但是一个月之后,当我需要用的时候,连续调试三天都没有出来,估计是模块烧了,建议;楼主在其引脚与单片机的io口加个限流电阻试一下效果。其它的就是看看接收的有没有存储在寄存器中,再看处理的是否有问题,一点一点的调试

出0入0汤圆

发表于 2011-7-31 10:37:00 | 显示全部楼层
这个,如果是51做的话,不用加限流电阻,我说的是89s52,如果avr的话,一定加,否则,直接烧。我有个经过测试的,当时无线模块是自己买的8引脚,其实10引脚就多了两个GND,一样的,我经过运行,好使的。lz要的话,加qq向我要吧。

出0入0汤圆

发表于 2011-8-2 21:59:20 | 显示全部楼层
我的没有调试出来,烦啊!用的LM3S的芯片

出0入0汤圆

发表于 2011-8-23 17:07:24 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-8-23 18:47:57 | 显示全部楼层
郁闷啊,我的芯片都坏几块了。

23楼得兄弟,模块烧了是怎么个现象。

我的是上电时IRQ输出直接是低了,要么MISO有数据输出,我怀疑是芯片坏掉了,单片机用的是PIC的,没加限流电阻,电源使用的是3.3V的

出0入0汤圆

发表于 2011-8-23 18:56:08 | 显示全部楼层
回复【楼主位】profcole  
-----------------------------------------------------------------------
楼主翻翻坛子里面关于NRF24L01的帖子。。。

出0入0汤圆

发表于 2011-8-23 19:03:40 | 显示全部楼层
我可以帮你搞的QQ475485272

出0入0汤圆

发表于 2011-8-26 15:32:50 | 显示全部楼层
回复【26楼】jiabin1024  
-----------------------------------------------------------------------

注意检查电路

出0入0汤圆

发表于 2011-8-30 13:52:26 | 显示全部楼层
我也为这个郁闷

出0入0汤圆

发表于 2011-8-30 15:41:22 | 显示全部楼层
mark~~~~

出0入0汤圆

发表于 2011-9-23 20:55:17 | 显示全部楼层
楼主辛苦了,不错的源码。

出0入0汤圆

发表于 2011-11-21 00:00:46 | 显示全部楼层
很好的源代码,中断那里受教了,无线部分期待有人能为楼主解答。

出0入0汤圆

发表于 2012-2-1 19:19:01 | 显示全部楼层
MARK,学习!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-29 10:54

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表