模吧

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

2732查看 | 14回复

[求助贴] 求助萝莉大神 NRF24l01程序移植问题请教

[复制链接]
发表于 2017-5-29 00:14:35 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
本帖最后由 ldy7474 于 2017-5-29 00:38 编辑

萝莉大神你好
嗯长话短说 语言表达能力不好近期在学习NRF24L01
网上抄的程序运行在STC15W408AS上没问题
我把发射部分移植到STC12C5A60S2上就不能正常通信硬件上确认无误
不知道具体错在哪里硬件是基于3代控做为开发
希望大神百忙之中抽一点点时间为学生解惑

压缩包里有3个对应的文件
求助萝莉大神    NRF24l01程序移植问题请教 萝莉,程序 作者:ldy7474 5323 文件打包合集.rar (96.38 KB, 下载次数: 8)

附上代码如下
#include <STC12C5A60S2.H>                                               
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned short

/**********  NRF24L01寄存器操作命令  **********************************************/
#define READ_REG        0x00    //读配置寄存器,低5位为寄存器地址
#define WRITE_REG       0x20    //写配置寄存器,低5位为寄存器地址
#define RD_RX_PLOAD     0x61    //读RX有效数据,1~32字节
#define WR_TX_PLOAD     0xA0    //写TX有效数据,1~32字节
#define FLUSH_TX        0xE1    //清除TX FIFO寄存器.发射模式下用
#define FLUSH_RX        0xE2    //清除RX FIFO寄存器.接收模式下用
#define REUSE_TX_PL     0xE3    //重新使用上一包数据,P_24L01_CE为高,数据包被不断发送.
#define NOP             0xFF    //空操作,可以用来读状态寄存器   
/**********  NRF24L01寄存器地址   **************************************************/
#define CONFIG          0x00    //配置寄存器地址                             
#define EN_AA           0x01    //使能自动应答功能
#define EN_RXADDR       0x02    //接收地址允许
#define SETUP_AW        0x03    //设置地址宽度(所有数据通道)
#define SETUP_RETR      0x04    //建立自动重发
#define RF_CH           0x05    //RF通道
#define RF_SETUP        0x06    //RF寄存器
#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有效数据宽度(1~32字节)
#define RX_PW_P1        0x12    // 接收数据通道1有效数据宽度(1~32字节)
#define RX_PW_P2        0x13    // 接收数据通道2有效数据宽度(1~32字节)
#define RX_PW_P3        0x14    // 接收数据通道3有效数据宽度(1~32字节)
#define RX_PW_P4        0x15    // 接收数据通道4有效数据宽度(1~32字节)
#define RX_PW_P5        0x16    // 接收数据通道5有效数据宽度(1~32字节)
#define FIFO_STATUS     0x17    // FIFO状态寄存器
/*********     24L01发送接收数据宽度定义      ***********/
#define ADR_WIDTH       5       //5字节地址宽度
#define DATA_WIDTH      32      //32字节有效数据宽度
#define NRF24L01_Tx_Mode  0x0e  //发送模式
#define NRF24L01_Rx_Mode  0x0f  //接收模式
#define FLUSH_TX        0xE1    //清除TX FIFO寄存器.发射模式下用
#define FLUSH_RX        0xE2    //清除RX FIFO寄存器.接收模式下用
/******NRF24L01引脚定义*******/

sbit NRF24L01_CE  =P0^0;
sbit NRF24L01_SCK =P0^1;
sbit NRF24L01_MISO=P0^2;
sbit NRF24L01_IRQ =P0^3;
sbit NRF24L01_MOSI=P0^4;
sbit NRF24L01_CSN =P0^5;

/****PWM输出LED引脚定义******/
sbit PWM_OUTR=P3^4;

uchar PWM_Write_Byte_R=1;

uchar code TX_ADDRESS[5]= {0x34,0x43,0x10,0x10,0x01};
//收发地址设置
//uchar code RX_ADDRESS[5]={0x34,0x43,0x10,0x10,0x01};
//接或收都必须一致
uchar Rx_Buffer[32];  //收到的数据最大32字节
uchar Tx_Buffer[32];  //待发送的数据,32字节

uchar RGB_PWM=0,RGB_Mode=0;
//R_PWM决定亮度,RGB_Mode决定状态和颜色

/***SPI初始化函数****/
uchar NRF24L01_SPI(uchar byte)
{
    uchar k;
    for(k=0;k<8;k++)// 输出8位                                            //每字节操作8次
    {
        NRF24L01_MISO=1;//默认为1
        NRF24L01_MOSI = (byte & 0x80);                          //发送最高位
        byte = (byte << 1);//传过来的数据左移                                     //字节左移
        NRF24L01_SCK = 1;//时钟拉高                                       //时钟上升沿
        byte |= NRF24L01_MISO;//读出的值给字节的最低位                                  //读出的位赋值给字节最低位
        NRF24L01_SCK = 0; //时钟拉低                                      //时钟下降沿
    }
    return(byte);                                               //读出的值返回  
}
/*********************************************/
/* 函数功能:给24L01的寄存器写值(一个字节) */
/* 入口参数:reg   要写的寄存器地址          */
/*           value 给寄存器写的值            */
/*********************************************/

void Write_Read_Reg(uchar reg,uchar value)
{
    NRF24L01_CSN=0; // 拉低                                            //CSN=0;   
    NRF24L01_SPI(reg); //写寄存器地址                                         //写寄存器地址
    NRF24L01_SPI(value);//给寄存器写命                                        //紧接着写入寄存器的命令码
    NRF24L01_CSN=1;//写完后拉高                                             //CSN=1;
}
/*********************************************/
/* 函数功能:写24L01的寄存器值(多个字节)   */
/* 入口参数:reg   寄存器地址命令                */
/*           *pBuf 指向数组的地址    */
/*           len   数组字节长度   */                 
/*********************************************/
void Write_Buffer(uchar reg, uchar *pBuf, uchar len)
{
    uchar k;
    NRF24L01_CSN=0;                                             //芯片的SPI功能选通
    NRF24L01_SPI(reg);//写命令                                          //写寄存器地址
    for(k=0; k<len; k++)// 输出8位
    {
        NRF24L01_SPI(*pBuf++);//把指针给SPI就OK                                 //写入数据
    }
    NRF24L01_CSN=1; //写完后拉高                                            //芯片关闭SPI功能
}
/*NRF24L01初始化过程*********/
void NRF24L01_Init(uchar Mode)
{
/*1 CE=0进入待机模式*********/
    NRF24L01_CE=0; //1,CE=0进入待机模式         
    NRF24L01_CSN=1;         
    NRF24L01_SCK=0;
    NRF24L01_CE=0;
/*2配置发射地址,字节长度和地址码值要与接收方一致**/
    Write_Buffer(0x20+TX_ADDR, TX_ADDRESS, ADR_WIDTH);   // 发送地址和收方地址一致
/*3配置接收应答地址,默认通道0做应答.字节长度码值与发射一致*********/   
    Write_Buffer(0x20+RX_ADDR_P0, TX_ADDRESS, ADR_WIDTH);// 选通道0作自动应答接收,地址、发送地址和收方地址一致
/*4配置接收通道默认0的数据接收长度,或者写入数据到发射缓冲区*********/
    Write_Read_Reg(0x20+RX_PW_P0, DATA_WIDTH);// 接收数据通道0有效数据宽度
/*5发射端 选择通道0作为自动应答.接收端选择通道0接收数据包*********/   
    Write_Read_Reg(0x20+EN_AA, 0x01);//使能通道0的自动应答
    Write_Read_Reg(0x20+EN_RXADDR, 0x01);//使能通道0的接收地址
/*6配置发射频率:总共126个频段,不同系统建议频段间隔大一点*********/   
    Write_Read_Reg(0x20+RF_CH, 40);//用频段40
/*7设置无线波特率1M/2M/250K.设置天线增益:0db发射距离最远*********/
    Write_Read_Reg(0x20+RF_SETUP, 0x0f);// 0db增益 2Mbps
/*8设置自动重发延时和重发次数,重发超过次数,IRQ中断输出低电平***/
    Write_Read_Reg(0x20+SETUP_RETR, 0x12);//设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次
/*9使能CRC校验,选择校验长度设置发送或者接受模式*********/
    Write_Read_Reg(0x20+CONFIG, Mode);
/*10,CE=1:进入发射空闲或者接收模式*********/
    //NRF_CE  =1;
}
/**********定时器初始化函数***********/
void Init(void) //52微秒
{
    TMOD|=0x01;
    TH0=0xff; //设置定时初值
    TL0=0x98;
    ET0=1;
    TR0=1; //定时器0开始计时
    EA=1;
    PWM_OUTR=1; //PWM输出脚置0
    NRF24L01_Init(NRF24L01_Tx_Mode);//Rx_Mode=0X0F设置为接收模式                            //2.4G模块初始化 发射
}
void RGB()
{
    uchar i;
    switch(RGB_Mode)         
    {

        case 0:                   //红色渐亮
                {
                    RGB_PWM+=1;
                    if(RGB_PWM==255)
                    {                       
                      RGB_Mode+=1;
                        }
                    for(i=0;i<24;)
                        {
                        Tx_Buffer[i+1]=RGB_PWM;   
                        i+=1;           
                        }
                  break;
                }                    
            default : RGB_Mode=0;break;   
            //如果上述条件都不成立,状态清0,退出。
    }
}
void LED_PWM_Timer0() interrupt 1
{
    static uchar pwm_t=0; //局部变量,不丢失数据
    TH0=0xff;
    TL0=0x98;
    if(pwm_t<Tx_Buffer[1])
    {
        PWM_OUTR=1;                                                            
    }
    else PWM_OUTR=0;                                                            
    pwm_t++;
    if(pwm_t>=255)      
    {
        pwm_t=0;
    }   
}

void main()
{   
    uint k;
    Init(); //定时器初始化                                                                  //初始化
    while(1)
    {   
        RGB();
        k=3000;
        while(k--);// 延时待系统稳定
        NRF24L01_CE=0;//1,CE=0进入待机模式
        NRF24L01_IRQ=1;//清除中断信号
        /**写RX有效数据,1~32字节  设置地址宽度**/                                                      
        Write_Buffer(WR_TX_PLOAD, Tx_Buffer, DATA_WIDTH);
                // 写入数据到发送缓冲器
        NRF24L01_CE=1;//写完之后准备接受拉高CE
        k=10;
        while(k--);
        /**然后清除STATUS 里面的中断各种杂七杂八的**/
       Write_Read_Reg(0x20+STATUS,0xff);
       //清除状态寄存器的所有中断
        NRF24L01_SPI(FLUSH_TX);
    }
}






 楼主| 发表于 2017-5-29 00:20:25 | 显示全部楼层
下面两个是调试通过能正常运行的程序 硬件是基于
6通道接收机

//发射
#include <STC15W408AS.H>                                              
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned short
/**********  NRF24L01寄存器操作命令  **********************************************/
#define READ_REG        0x00    //读配置寄存器,低5位为寄存器地址
#define WRITE_REG       0x20    //写配置寄存器,低5位为寄存器地址
#define RD_RX_PLOAD     0x61    //读RX有效数据,1~32字节
#define WR_TX_PLOAD     0xA0    //写TX有效数据,1~32字节
#define FLUSH_TX        0xE1    //清除TX FIFO寄存器.发射模式下用
#define FLUSH_RX        0xE2    //清除RX FIFO寄存器.接收模式下用
#define REUSE_TX_PL     0xE3    //重新使用上一包数据,P_24L01_CE为高,数据包被不断发送.
#define NOP             0xFF    //空操作,可以用来读状态寄存器   
/**********  NRF24L01寄存器地址   **************************************************/
#define CONFIG          0x00    //配置寄存器地址                             
#define EN_AA           0x01    //使能自动应答功能
#define EN_RXADDR       0x02    //接收地址允许
#define SETUP_AW        0x03    //设置地址宽度(所有数据通道)
#define SETUP_RETR      0x04    //建立自动重发
#define RF_CH           0x05    //RF通道
#define RF_SETUP        0x06    //RF寄存器
#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有效数据宽度(1~32字节)
#define RX_PW_P1        0x12    // 接收数据通道1有效数据宽度(1~32字节)
#define RX_PW_P2        0x13    // 接收数据通道2有效数据宽度(1~32字节)
#define RX_PW_P3        0x14    // 接收数据通道3有效数据宽度(1~32字节)
#define RX_PW_P4        0x15    // 接收数据通道4有效数据宽度(1~32字节)
#define RX_PW_P5        0x16    // 接收数据通道5有效数据宽度(1~32字节)
#define FIFO_STATUS     0x17    // FIFO状态寄存器
/*********     24L01发送接收数据宽度定义      ***********/
#define ADR_WIDTH       5       //5字节地址宽度
#define DATA_WIDTH      32      //32字节有效数据宽度
#define NRF24L01_Tx_Mode  0x0e  //发送模式
#define NRF24L01_Rx_Mode  0x0f  //接收模式
#define FLUSH_TX        0xE1    //清除TX FIFO寄存器.发射模式下用
#define FLUSH_RX        0xE2    //清除RX FIFO寄存器.接收模式下用
/******NRF24L01引脚定义*******/
sbit NRF24L01_CSN =P1^2;
sbit NRF24L01_CE  =P5^5;
sbit NRF24L01_SCK =P5^4;
sbit NRF24L01_MOSI=P1^3;
sbit NRF24L01_MISO=P1^5;
sbit NRF24L01_IRQ =P1^4;
/****PWM输出LED引脚定义******/
sbit PWM_OUTR=P1^0;


uchar PWM_Write_Byte_R=1;
uchar PWM_Write_Byte_G=1;
uchar PWM_Write_Byte_B=1;
uchar code TX_ADDRESS[5]= {0x34,0x43,0x10,0x10,0x01};
//收发地址设置
//uchar code RX_ADDRESS[5]={0x34,0x43,0x10,0x10,0x01};
//接或收都必须一致
uchar NRF24L01_Rx_Buffer[32];  //收到的数据最大32字节
uchar NRF24L01_Tx_Buffer[32];  //待发送的数据,32字节

uchar RGB_PWM=0,RGB_Mode=0;
//R_PWM决定亮度,RGB_Mode决定状态和颜色

/***SPI初始化函数****/
uchar NRF24L01_SPI(uchar byte)
{
    uchar k;
    for(k=0;k<8;k++)// 输出8位                                            //每字节操作8次
    {
        NRF24L01_MISO=1;//默认为1
        NRF24L01_MOSI = (byte & 0x80);                          //发送最高位
        byte = (byte << 1);//传过来的数据左移                                     //字节左移
        NRF24L01_SCK = 1;//时钟拉高                                       //时钟上升沿
        byte |= NRF24L01_MISO;//读出的值给字节的最低位                                  //读出的位赋值给字节最低位
        NRF24L01_SCK = 0; //时钟拉低                                      //时钟下降沿
    }
    return(byte);                                               //读出的值返回  
}
/*********************************************/
/* 函数功能:给24L01的寄存器写值(一个字节) */
/* 入口参数:reg   要写的寄存器地址          */
/*           value 给寄存器写的值            */
/*********************************************/

void NRF24L01_Write_Read_Reg(uchar reg,uchar value)
{
    NRF24L01_CSN=0; // 拉低                                            //CSN=0;   
    NRF24L01_SPI(reg); //写寄存器地址                                         //写寄存器地址
    NRF24L01_SPI(value);//给寄存器写命                                        //紧接着写入寄存器的命令码
    NRF24L01_CSN=1;//写完后拉高                                             //CSN=1;
}
/*********************************************/
/* 函数功能:写24L01的寄存器值(多个字节)   */
/* 入口参数:reg   寄存器地址命令                */
/*           *pBuf 指向数组的地址    */
/*           len   数组字节长度   */                 
/*********************************************/
void NRF24L01_Write_Buffer(uchar reg, uchar *pBuf, uchar len)
{
    uchar k;
    NRF24L01_CSN=0;                                             //芯片的SPI功能选通
    NRF24L01_SPI(reg);//写命令                                          //写寄存器地址
    for(k=0; k<len; k++)// 输出8位
    {
        NRF24L01_SPI(*pBuf++);//把指针给SPI就OK                                 //写入数据
    }
    NRF24L01_CSN=1; //写完后拉高                                            //芯片关闭SPI功能
}
/*NRF24L01初始化过程*********/
void NRF24L01_Init(uchar Mode)
{
/*1 CE=0进入待机模式*********/
    NRF24L01_CE=0; //1,CE=0进入待机模式         
    NRF24L01_CSN=1;         
    NRF24L01_SCK=0;
    NRF24L01_CE=0;
/*2配置发射地址,字节长度和地址码值要与接收方一致**/
    NRF24L01_Write_Buffer(0x20+TX_ADDR, TX_ADDRESS, ADR_WIDTH);   // 发送地址和收方地址一致
/*3配置接收应答地址,默认通道0做应答.字节长度码值与发射一致*********/   
    NRF24L01_Write_Buffer(0x20+RX_ADDR_P0, TX_ADDRESS, ADR_WIDTH);// 选通道0作自动应答接收,地址、发送地址和收方地址一致
/*4配置接收通道默认0的数据接收长度,或者写入数据到发射缓冲区*********/
    NRF24L01_Write_Read_Reg(0x20+RX_PW_P0, DATA_WIDTH);// 接收数据通道0有效数据宽度
/*5发射端 选择通道0作为自动应答.接收端选择通道0接收数据包*********/   
    NRF24L01_Write_Read_Reg(0x20+EN_AA, 0x01);//使能通道0的自动应答
    NRF24L01_Write_Read_Reg(0x20+EN_RXADDR, 0x01);//使能通道0的接收地址
/*6配置发射频率:总共126个频段,不同系统建议频段间隔大一点*********/   
    NRF24L01_Write_Read_Reg(0x20+RF_CH, 40);//用频段40
/*7设置无线波特率1M/2M/250K.设置天线增益:0db发射距离最远*********/
    NRF24L01_Write_Read_Reg(0x20+RF_SETUP, 0x0f);// 0db增益 2Mbps
/*8设置自动重发延时和重发次数,重发超过次数,IRQ中断输出低电平***/
    NRF24L01_Write_Read_Reg(0x20+SETUP_RETR, 0x12);//设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次
/*9使能CRC校验,选择校验长度设置发送或者接受模式*********/
    NRF24L01_Write_Read_Reg(0x20+CONFIG, Mode);
/*10,CE=1:进入发射空闲或者接收模式*********/
    //NRF_CE  =1;
}
/**********定时器初始化函数***********/
void Init(void) //52微秒
{
    TMOD|=0x01;
    TH0=0xff; //设置定时初值
    TL0=0x98;
    ET0=1;
    TR0=1; //定时器0开始计时
    EA=1;
    PWM_OUTR=1; //PWM输出脚置0
    NRF24L01_Init(NRF24L01_Tx_Mode);//Rx_Mode=0X0F设置为接收模式                            //2.4G模块初始化 发射
}
void RGB()
{
    uchar i;
    switch(RGB_Mode)         
    {

        case 0:                   //红色渐亮
                {
                    RGB_PWM+=1;
                    if(RGB_PWM==255)
                    {                      
                      RGB_Mode+=1;
                        }
                    for(i=0;i<24;)
                        {
                        NRF24L01_Tx_Buffer[i+1]=RGB_PWM;   
                        i+=1;          
                        }
                  break;
                }                   
            default : RGB_Mode=0;break;   
            //如果上述条件都不成立,状态清0,退出。
    }
}
void LED_PWM_Timer0() interrupt 1
{
    static uchar pwm_t=0; //局部变量,不丢失数据
    TH0=0xff;
    TL0=0x98;
    if(pwm_t<NRF24L01_Tx_Buffer[1])
    {
        PWM_OUTR=1;                                                            
    }
    else PWM_OUTR=0;                                                            
    pwm_t++;
    if(pwm_t>=255)      
    {
        pwm_t=0;
    }   
}

void main()
{   
    uint k;
    Init(); //定时器初始化                                                                  //初始化
    while(1)
    {   
        RGB();
        k=3000;
        while(k--);// 延时待系统稳定
        NRF24L01_CE=0;//1,CE=0进入待机模式
        NRF24L01_IRQ=1;//清除中断信号
        /**写RX有效数据,1~32字节  设置地址宽度**/                                                      
        NRF24L01_Write_Buffer(WR_TX_PLOAD, NRF24L01_Tx_Buffer, DATA_WIDTH); // 写入数据到发送缓冲器
        NRF24L01_CE=1;//写完之后准备接受拉高CE
        k=10;
        while(k--);
        /**然后清除STATUS 里面的中断各种杂七杂八的**/
        NRF24L01_Write_Read_Reg(0x20+STATUS,0xff);
       //清除状态寄存器的所有中断
        NRF24L01_SPI(FLUSH_TX);
    }
}

/**********************************************/
//接收
#include <STC15W408AS.H>                                      
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned short
/**********  NRF24L01寄存器操作命令  **********************************************/
#define READ_REG        0x00    //读配置寄存器,低5位为寄存器地址
#define WRITE_REG       0x20    //写配置寄存器,低5位为寄存器地址
#define RD_RX_PLOAD     0x61    //读RX有效数据,1~32字节
#define WR_TX_PLOAD     0xA0    //写TX有效数据,1~32字节
#define FLUSH_TX        0xE1    //清除TX FIFO寄存器.发射模式下用
#define FLUSH_RX        0xE2    //清除RX FIFO寄存器.接收模式下用
#define REUSE_TX_PL     0xE3    //重新使用上一包数据,P_24L01_CE为高,数据包被不断发送.
#define NOP             0xFF    //空操作,可以用来读状态寄存器   
/**********  NRF24L01寄存器地址   **************************************************/
#define CONFIG          0x00    //配置寄存器地址                             
#define EN_AA           0x01    //使能自动应答功能
#define EN_RXADDR       0x02    //接收地址允许
#define SETUP_AW        0x03    //设置地址宽度(所有数据通道)
#define SETUP_RETR      0x04    //建立自动重发
#define RF_CH           0x05    //RF通道
#define RF_SETUP        0x06    //RF寄存器
#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有效数据宽度(1~32字节)
#define RX_PW_P1        0x12    // 接收数据通道1有效数据宽度(1~32字节)
#define RX_PW_P2        0x13    // 接收数据通道2有效数据宽度(1~32字节)
#define RX_PW_P3        0x14    // 接收数据通道3有效数据宽度(1~32字节)
#define RX_PW_P4        0x15    // 接收数据通道4有效数据宽度(1~32字节)
#define RX_PW_P5        0x16    // 接收数据通道5有效数据宽度(1~32字节)
#define FIFO_STATUS     0x17    // FIFO状态寄存器
/*********     24L01发送接收数据宽度定义      ***********/
#define ADR_WIDTH       5       //5字节地址宽度
#define DATA_WIDTH      32      //32字节有效数据宽度
#define NRF24L01_Tx_Mode  0x0e  //发送模式
#define NRF24L01_Rx_Mode  0x0f  //接收模式
#define FLUSH_TX        0xE1    //清除TX FIFO寄存器.发射模式下用
#define FLUSH_RX        0xE2    //清除RX FIFO寄存器.接收模式下用
/******NRF24L01引脚定义*******/
sbit NRF24L01_CSN =P1^2;
sbit NRF24L01_CE  =P5^5;
sbit NRF24L01_SCK =P5^4;
sbit NRF24L01_MOSI=P1^3;
sbit NRF24L01_MISO=P1^5;
sbit NRF24L01_IRQ =P1^4;
/****PWM输出LED引脚定义******/
sbit PWM_OUTR=P1^0;


uchar PWM_Write_Byte_R=1;
uchar code TX_ADDRESS[ADR_WIDTH]  = {0x34,0x43,0x10,0x10,0x01}; //收发地址设置
uchar NRF24L01_Rx_Buffer[DATA_WIDTH];                           //收到的数据最大32字节
uchar NRF24L01_Tx_Buffer[DATA_WIDTH];                           //待发送的数据,32字节

uchar NRF24L01_SPI(uchar byte)
{
    uchar k;
    for(k=0;k<8;k++)                                            //每字节操作8次
    {
        NRF24L01_MISO=1;
        NRF24L01_MOSI = (byte & 0x80);                          //发送最高位
        byte = (byte << 1);                                     //字节左移
        NRF24L01_SCK = 1;                                       //时钟上升沿
        byte |= NRF24L01_MISO;                                  //读出的位赋值给字节最低位
        NRF24L01_SCK = 0;                                       //时钟下降沿
    }
    return(byte);                                               //读出的值返回       
}

void NRF24L01_Write_Read_Reg(uchar reg,uchar value)
{
    NRF24L01_CSN=0;                                             //CSN=0;   
    NRF24L01_SPI(reg);                                          //写寄存器地址
    NRF24L01_SPI(value);                                        //紧接着写入寄存器的命令码
    NRF24L01_CSN=1;                                             //CSN=1;
}

void NRF24L01_Read_Buffer(uchar reg,uchar *pBuf,uchar len)
{
    uchar k;
    NRF24L01_CSN=0;                                             //CSN=0      
    NRF24L01_SPI(reg);                                          //写寄存器地址
    for(k=0;k<len;k++)
    {
        pBuf[k]=NRF24L01_SPI(0XFF);                             //读出数据
    }
    NRF24L01_CSN=1;                                                 //CSN=1
}

void NRF24L01_Write_Buffer(uchar reg, uchar *pBuf, uchar len)
{
    uchar k;
    NRF24L01_CSN=0;                                             //芯片的SPI功能选通
    NRF24L01_SPI(reg);                                          //写寄存器地址
    for(k=0; k<len; k++)
    {
        NRF24L01_SPI(*pBuf++);                                      //写入数据
    }
    NRF24L01_CSN=1;                                             //芯片关闭SPI功能
}

void NRF24L01_Init(uchar Mode)
{
    NRF24L01_CE=0;             
    NRF24L01_CSN=1;            
    NRF24L01_SCK=0;
    NRF24L01_CE=0;
    NRF24L01_Write_Buffer(0x20+TX_ADDR, TX_ADDRESS, ADR_WIDTH);   // 发送地址和收方地址一致
    NRF24L01_Write_Buffer(0x20+RX_ADDR_P0, TX_ADDRESS, ADR_WIDTH);// 选通道0作自动应答接收,地址、发送地址和收方地址一致
    NRF24L01_Write_Read_Reg(0x20+RX_PW_P0, DATA_WIDTH);         // 接收数据通道0有效数据宽度
    NRF24L01_Write_Read_Reg(0x20+EN_AA, 0x01);                  //使能通道0的自动应答
    NRF24L01_Write_Read_Reg(0x20+EN_RXADDR, 0x01);              //使能通道0的接收地址
    NRF24L01_Write_Read_Reg(0x20+RF_CH, 40);                    //设置RF通道为125
    NRF24L01_Write_Read_Reg(0x20+RF_SETUP, 0x0f);               // 0db增益 2Mbps
    NRF24L01_Write_Read_Reg(0x20+SETUP_RETR, 0x12);             //设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次
    NRF24L01_Write_Read_Reg(0x20+CONFIG, Mode);
}

void Init(void)
{
    TMOD|=0x01;
    TH0=0xff;
    TL0=0x98;
    ET0=1;
    TR0=1;
    EA=1;
    PWM_OUTR=1;     //PWM输出脚置0

    NRF24L01_Init(NRF24L01_Rx_Mode);                            //2.4G模块初始化 发射
}

void LED_PWM_Timer0() interrupt 1
{
    static uchar pwm_t=0;                                       //局部变量,不丢失数据
    TH0=0xff;
    TL0=0x98;
    if(pwm_t<NRF24L01_Rx_Buffer[1])
    {
        PWM_OUTR=1;                                                                    
    }
    else PWM_OUTR=0;

    pwm_t++;
    if(pwm_t>=255)         
    {
        pwm_t=0;
    }
}
void main()
{   
    uint k;
    Init();                                                                     //初始化
    while(1)
    {   
        k=10000;
        while(k--);
        NRF24L01_CE=0;
        NRF24L01_IRQ=1;
        NRF24L01_Read_Buffer(RD_RX_PLOAD,NRF24L01_Rx_Buffer,DATA_WIDTH);
        NRF24L01_CE=1;

        NRF24L01_Write_Read_Reg(0x20+STATUS,0xff);              //清除状态寄存器的所有中断
        NRF24L01_SPI(FLUSH_RX);                                 //清除RX FIFO寄存器.接收模式下用

    }
}

发表于 2017-5-29 07:37:50 | 显示全部楼层
路过帮顶 太长了
发表于 2017-5-29 11:27:33 | 显示全部楼层
程序能在15W上运行就一定也能在12C上运行,没有什么区别。三代控就是12C,12通道的接收机也是12C,你可以用三代的源码试试
 楼主| 发表于 2017-5-29 13:10:22 | 显示全部楼层
我爱萝丽爱萝丽 发表于 2017-5-29 11:27 求助萝莉大神    NRF24l01程序移植问题请教 萝莉,程序 作者:ldy7474 8964
程序能在15W上运行就一定也能在12C上运行,没有什么区别。三代控就是12C,12通道的接收机也是12C,你可以用 ...

这我就纳闷了  仔细对过引脚定义  本来想移植到12C然后发送ADC值给接收  悲剧的是调不通
我再试试看  发射接收晶振都是12m  

我用两个408接收机实验过发送24m接收12m也能正常通信只是接收响应慢一倍左右
排除了两边频率不一样收不到数据的可能性
求助萝莉大神    NRF24l01程序移植问题请教 萝莉,程序 作者:ldy7474 8788 求助萝莉大神    NRF24l01程序移植问题请教 萝莉,程序 作者:ldy7474 2153 求助萝莉大神    NRF24l01程序移植问题请教 萝莉,程序 作者:ldy7474 304 这玩意真的好难搞

发表于 2017-5-29 20:51:16 | 显示全部楼层
好高深.....頂一個
发表于 2017-5-30 00:32:43 | 显示全部楼层
有点高深,表示不懂。
发表于 2017-6-2 08:42:37 | 显示全部楼层
萝莉的有自己的通信密码吧

发表于 2017-6-6 13:46:59 | 显示全部楼层
我爱萝丽爱萝丽 发表于 2017-5-29 11:27
程序能在15W上运行就一定也能在12C上运行,没有什么区别。三代控就是12C,12通道的接收机也是12C,你可以用 ...

求萝莉群号
发表于 2017-6-6 15:15:25 | 显示全部楼层
表示完全搞不懂
发表于 2017-9-26 13:22:59 | 显示全部楼层
虽然不懂,还是顶起把。。
发表于 2017-10-2 09:09:34 | 显示全部楼层
我也不懂,帮顶。
发表于 2017-10-4 21:45:17 | 显示全部楼层

272416403  拿走不谢
发表于 2017-10-4 21:45:19 | 显示全部楼层

272416403  拿走不谢
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

QQ|关于模吧|APP下载|广告报价|手机版|企业会员|商城入驻|联系我们|模吧 ( 黔ICP备2022002348号-1 )

© 2013-2020 Moz8.com 模吧,玩出精彩!