搜索
bottom↓
回复: 7

请问如何使用nrf2401的直接模式 ?

[复制链接]

出0入0汤圆

发表于 2009-8-15 13:53:15 | 显示全部楼层 |阅读模式
目前因为一些需要需要使用NRF2401的直接模式,但是直接模式总是调不通,无法分辨出有效数据...
如果那位兄台有调过这个请赐教一二,如果能给部分源代码更好。
或者有射频通信直接模式相关的资料,能提供给小弟一份...
NRF2401 direct mode
我的邮箱是quss2008@163.com

出0入0汤圆

发表于 2009-8-15 14:00:33 | 显示全部楼层
以前有 PIC写过 好久不用了  给你个测试程序吧  希望能对你有用

发送模块

#include<p18f4550.h>
#include<delays.h>
//
/*************************************************************
                       引脚连接宏定义
*************************************************************/
#define DATA       LATBbits.LATB0//频道1收发数据端
#define CLK1       LATBbits.LATB1//频道1时钟
#define DR1        LATBbits.LATB2//频道1数据已准备好
#define CS         LATBbits.LATB3//配置模式片选
#define CE         LATBbits.LATB4//收发状态控制
#define PWR_UP     LATBbits.LATB5//芯片唤醒
//
/*************************************************************
                       状态切换宏定义
*************************************************************/
#define NRF2401_Mode_RT()        PWR_UP=1;CE=1;CS=0;//收发
#define NRF2401_Mode_Deploy()    PWR_UP=1;CE=0;CS=1;//配置
#define NRF2401_Mode_Free()      PWR_UP=1;CE=0;CS=0;//空闲
#define NRF2401_Mode_Off()       PWR_UP=0//关机
//
/*************************************************************
                       测试用数据
*************************************************************/
const unsigned char Dat[10]=
{
1,
2,
3,
4,
5,
6,
7,
8,
9,
10
};
const unsigned char Add[4]=
{//目标地址000000ff
0x00,0x00,0x00,0xff
};
/*************************************************************
                       NRF2401配置数据
备    注:当芯片未掉电,且需要切换收发方式时仅需要发送一个字节
*************************************************************/
const unsigned char NRF2401_Deploy_Data[15]=
{
    0x50,//DATA2_W通道二数据包长度80bit(10byte),DATA2_W<=256-ADDR_W-CRC(bit)
    0x50,//DATA2_W通道一数据包长度,DATA1_W<=256-ADDR_W-CRC(bit)
    0x00,//通道二地址(A24),ADDR2
    0x00,//通道二地址(A23)
    0x00,//通道二地址(A22)
    0x00,//通道二地址(A21)
    0x02,//通道二地址(A20)
    0x00,//通道一地址(A14),ADDR1=0x00000000fe
    0x00,//通道一地址(A13)
    0x00,//通道一地址(A12)
    0x00,//通道一地址(A11)
    0xfe,//通道一地址(A10)
    0x83,//b7~b2:接收地址宽度32位,(和发送端一致,不超过40bit),ADDR_W
         //b1~b0:16CRC模式(01-8bit;11-16bit;00/10-no);b1,CRC_L;b0,CRC_EN
    0x6F,//b15:通道二禁止(0-通道1;1-通道1和2),RX2_EN
         //b14:通讯模式为ShockBurat(0-Direct模式,1-ShockBurst模式),CM
         //b13:通信速率为1M(0-250Kbps;1-1Mbps),RFDR_SB
         //b12~b10:晶振选择16M(000-4M;001-8M;010-12M;011-16M),XO_F
         //b9~b8:发射功率0db(00,01,10,11>-20db,-10db,-5db,0db),RF_PWR
    0x04 //b7~b1:频道选择4,RF_CH#
         //b0:收发控制(0-发送;1-接收),RXEN
};
//
/*************************************************************
                   IO初始化函数
函数名称:Init_IOforNRF2401();
输入参数:无
输出参数:无
备    注:无

*************************************************************/
void Init_IOforNRF2401(void)
{
TRISBbits.TRISB0=0;//设置DATA引脚为输出
TRISBbits.TRISB1=0;//设置CLK引脚为输出
TRISBbits.TRISB2=1;//设置DR1引脚为输入
TRISBbits.TRISB3=0;//设置CS引脚为输出
TRISBbits.TRISB4=0;//设置CE引脚为输出
TRISBbits.TRISB5=0;//设置PWR_UP引脚为输出
}
//
/*************************************************************
                   数据串行通信函数
函数名称:NRF2401_DataSerialSend();
输入参数:待发送数据块首地址,待发送数据个数
输出参数:无
备    注:调用前要对NRF2401的工作模式做相应的设定

*************************************************************/
void NRF2401_DataSerialSend(unsigned char *p,unsigned char n)
{
unsigned char i,j;
//
unsigned char d;
//
TRISBbits.TRISB0=0;//设置DATA引脚为输出
TRISBbits.TRISB1=0;//设置CLK引脚为输出
//
CLK1=0;
LATAbits.LATA5 = 0;
for(i=0;i<n;i++)//字节数
   {
     d=*(p++);
    for(j=0;j<8;j++)
       {
        if(d&0x80)//MSB
           {
            DATA=1;//数据建立时间>500nS
           }
        else
           {
            DATA=0;
           }
        //Nop();
        CLK1=1;//最短时钟宽度500nS
       d<<=1;
       // Nop();
       CLK1=0;
       }
   }
LATAbits.LATA5 = 1;
DATA=0;
}
//
/*************************************************************
                   NRF2401初始化配置
函数名称:NRF2401_Init();
输入参数:无
输出参数:无
备    注:具体配置见NRF2401_Deploy_Data数组
          该函数为15个字节全部配置
          若只需要改变收发状态,仅需发送NRF2401_Deploy_Data[14]
                                       
*************************************************************/
void NRF2401_Init(void)
{
NRF2401_Mode_Free();//进入待机
Delay1KTCYx(3);//由待机进入配置延时3mS
NRF2401_Mode_Deploy();//进入配置模式时引脚保持时间>5uS,两次通信间隔>50nS
Delay10TCYx(3);
NRF2401_DataSerialSend((unsigned char *)NRF2401_Deploy_Data,15);//发送数据
NRF2401_Mode_RT();//从配置模式退出,进入到收发模式,使配置有效
Delay10TCYx(2);
}
//
/*************************************************************
                   NRF2401收发状态配置
函数名称:NRF2401_R_and_T();
输入参数:n   n>0  收状态
              n=0  发状态
          ch  要选择的频道
输出参数:无
备    注:用于更改收发模式和通信频道
          最后两个字节具体配置见NRF2401_Deploy_Data数组
          仅用于NRF2401被配置过,且没有掉电的情况

*************************************************************/
void NRF2401_R_and_T(unsigned char n,unsigned char ch)
{
unsigned char i;
NRF2401_Mode_Deploy();//进入配置模式,保持时间>5uS
Delay10TCYx(2);
if(n)
   {   
    i=(ch<<1)|0x01;
   }
else
   {
    i=(ch<<1)&0xfe;
   }
NRF2401_DataSerialSend(&i,1);
NRF2401_Mode_RT();//从配置模式退出,进入到收发模式
Delay10TCYx(2);
}
//
/*************************************************************
                   NRF2401发送数据
函数名称:NRF2401_Send();
输入参数:*Add   发送目标地址
          *Dat   待发送数据块首地址
输出参数:无
备    注:确保该函数执行前NRF2401处于发射状态

*************************************************************/
void NRF2401_Send(unsigned char *Add,unsigned char *Dat)
{
NRF2401_Mode_RT();//配置芯片为收发模式
//Delay10TCYx(1);//建立时间>5uS
NRF2401_DataSerialSend(Add,4);//32位地址,根据最初的配置信息改动,或者NRF2401_Deploy_Data[12]>>2表示
NRF2401_DataSerialSend(Dat,10);//10bety数据,根据最初的配置信息改动,或者NRF2401_Deploy_Data[1]表示
NRF2401_Mode_Free();//拉低CE,使芯片开始发送
}
//
/*************************************************************
                           主函数

*************************************************************/
void main(void)
{
//unsigned char i=0xaa;
TRISAbits.TRISA5=0;//LED
LATAbits.LATA5=0;
Init_IOforNRF2401();//初始化端口
NRF2401_Init();//按表格配置NRF2401
while(1)
   {
NRF2401_Send((unsigned char *)Add,(unsigned char *)Dat);
Delay10KTCYx(100);
   }
}

出0入0汤圆

发表于 2009-8-15 14:01:02 | 显示全部楼层
接收 模块

#include<p18f4550.h>
#include<delays.h>
//
/*************************************************************
                       引脚连接宏定义
*************************************************************/
#define DATA       LATBbits.LATB0//频道1收发数据端
#define CLK1       LATBbits.LATB1//频道1时钟
#define DR1        LATBbits.LATB2//频道1数据已准备好
#define CS         LATBbits.LATB3//配置模式片选
#define CE         LATBbits.LATB4//收发状态控制
#define PWR_UP     LATBbits.LATB5//芯片唤醒
//
/*************************************************************
                       状态切换宏定义
*************************************************************/
#define NRF2401_Mode_RT()        PWR_UP=1;CE=1;CS=0;//收发
#define NRF2401_Mode_Deploy()    PWR_UP=1;CE=0;CS=1;//配置
#define NRF2401_Mode_Free()      PWR_UP=1;CE=0;CS=0;//空闲
#define NRF2401_Mode_Off()       PWR_UP=0//关机
//
/*************************************************************
                       测试用数据
*************************************************************/
const unsigned char Dat[10]=
{
1,
2,
3,
4,
5,
6,
7,
8,
9,
10
};
//
/*************************************************************
                       NRF2401配置数据
备    注:当芯片未掉电,且需要切换收发方式时仅需要发送一个字节
*************************************************************/
const unsigned char NRF2401_Deploy_Data[15]=
{
    0x50,//DATA2_W通道二数据包长度80bit(10byte),DATA2_W<=256-ADDR_W-CRC(bit)
    0x50,//DATA2_W通道一数据包长度,DATA1_W<=256-ADDR_W-CRC(bit)
    0x00,//通道二地址(A24),ADDR2
    0x00,//通道二地址(A23)
    0x00,//通道二地址(A22)
    0x00,//通道二地址(A21)
    0x02,//通道二地址(A20)
    0x00,//通道一地址(A14),ADDR1=0x00000000ff
    0x00,//通道一地址(A13)
    0x00,//通道一地址(A12)
    0x00,//通道一地址(A11)
    0xff,//通道一地址(A10)
    0x83,//b7~b2:接收地址宽度32位,(和发送端一致,不超过40bit),ADDR_W
         //b1~b0:16CRC模式(01-8bit;11-16bit;00/10-no);b1,CRC_L;b0,CRC_EN
    0x6F,//b15:通道二禁止(0-通道1;1-通道1和2),RX2_EN
         //b14:通讯模式为ShockBurat(0-Direct模式,1-ShockBurst模式),CM
         //b13:通信速率为1M(0-250Kbps;1-1Mbps),RFDR_SB
         //b12~b10:晶振选择16M(000-4M;001-8M;010-12M;011-16M),XO_F
         //b9~b8:发射功率0db(00,01,10,11>-20db,-10db,-5db,0db),RF_PWR
    0x05 //b7~b1:频道选择4,RF_CH#
         //b0:配置成收模式(0-发送;1-接收),RXEN
};
//
/*************************************************************
                   IO初始化函数
函数名称:Init_IOforNRF2401();
输入参数:无
输出参数:无
备    注:无

*************************************************************/
void Init_IOforNRF2401(void)
{
TRISBbits.TRISB0=0;//设置DATA引脚为输出
TRISBbits.TRISB1=0;//设置CLK引脚为输出
TRISBbits.TRISB2=1;//设置DR1引脚为输入
TRISBbits.TRISB3=0;//设置CS引脚为输出
TRISBbits.TRISB4=0;//设置CE引脚为输出
TRISBbits.TRISB5=0;//设置PWR_UP引脚为输出
}
//
/*************************************************************
                   数据串行发送函数
函数名称:NRF2401_DataSerialSend();
输入参数:待发送数据块首地址,待发送数据个数
输出参数:无
备    注:调用前要对NRF2401的工作模式做相应的设定

*************************************************************/
void NRF2401_DataSerialSend(unsigned char *p,unsigned char n)
{
unsigned char i,j;
//
unsigned char d;
//
TRISBbits.TRISB0=0;//设置DATA引脚为输出
TRISBbits.TRISB1=0;//设置CLK引脚为输出
//
CLK1=0;
for(i=0;i<n;i++)//字节数
   {

     d=*(p++);
    for(j=0;j<8;j++)
       {
      
        if(d&0x80)//MSB
           {
            DATA=1;//数据建立时间>500nS
           }
        else
           {
            DATA=0;
           }
        //Nop();
       // Nop();
        CLK1=1;//最短时钟宽度500nS
       d<<=1;
        //Nop();
        //        Nop();
        CLK1=0;
       }
   }
DATA=0;
//CLK1=0;
}
//
/*************************************************************
                   数据串行读取函数
函数名称:NRF2401_DataSerialRead();
输入参数:接收数觉存储区首地址,接收数觉个数
输出参数:接收是否与设置吻合
备    注:调用前要对NRF2401的工作模式做相应的设定

*************************************************************/
unsigned char NRF2401_DataSerialRead(unsigned char *p,unsigned char n)
{
unsigned char i,j;
unsigned char d;
TRISBbits.TRISB0=1;//设置DATA引脚为输入
TRISBbits.TRISB1=0;//设置CLK引脚为输出
CLK1=0;
for(i=0;i<n;i++)
    {
   
    for(j=0;j<8;j++)
       {
        d<<=1;
        CLK1=1;
       if(PORTBbits.RB0==1)
           {
            d|=0x01;
           }
        else
           {
            d&=0xfe;
           }
        CLK1=0;
        //Nop();
       // Nop();
        }
     p=d;
    }
}
//
/*************************************************************
                   NRF2401初始化配置
函数名称:NRF2401_Init();
输入参数:无
输出参数:无
备    注:具体配置见NRF2401_Deploy_Data数组
          该函数为15个字节全部配置
          若只需要改变收发状态,仅需发送NRF2401_Deploy_Data[14]
                                       
*************************************************************/
void NRF2401_Init(void)
{
NRF2401_Mode_Free();//进入待机
Delay1KTCYx(3);//由待机进入配置延时3mS
NRF2401_Mode_Deploy();//进入配置模式时引脚保持时间>5uS,两次通信间隔>50nS
Delay10TCYx(3);
NRF2401_DataSerialSend((unsigned char *)NRF2401_Deploy_Data,15);//发送数据
NRF2401_Mode_RT();//从配置模式退出,进入到收发模式,使配置有效
}
//
/*************************************************************
                   NRF2401收发状态配置
函数名称:NRF2401_R_and_T();
输入参数:n   n>0  收状态
              n=0  发状态
          ch  要选择的频道
输出参数:无
备    注:用于更改收发模式和通信频道
          最后两个字节具体配置见NRF2401_Deploy_Data数组
          仅用于NRF2401被配置过,且没有掉电的情况

*************************************************************/
void NRF2401_R_and_T(unsigned char n,unsigned char ch)
{
unsigned char i;
NRF2401_Mode_Deploy();//进入配置模式,保持时间>5uS
Delay10TCYx(2);
if(n)
   {   
    i=(ch<<1)|0x01;
   }
else
   {
    i=(ch<<1)&0xfe;
   }
NRF2401_DataSerialSend(&i,1);
NRF2401_Mode_RT();//从配置模式退出,进入到收发模式
Delay10TCYx(2);
}
//
/*************************************************************
                   NRF2401发送数据
函数名称:NRF2401_Send();
输入参数:*Add   发送目标地址
          *Dat   待发送数据块首地址
输出参数:无
备    注:确保该函数执行前NRF2401处于发射状态

*************************************************************/
void NRF2401_Send(unsigned char *Add,unsigned char *Dat)
{
NRF2401_Mode_RT();//配置芯片为收发模式
//Delay10TCYx(2);//建立时间>5uS
NRF2401_DataSerialSend(Add,4);//32位地址,根据最初的配置信息改动,或者NRF2401_Deploy_Data[12]>>2表示
NRF2401_DataSerialSend(Dat,10);//10bety数据,根据最初的配置信息改动,或者NRF2401_Deploy_Data[1]表示
NRF2401_Mode_Free();//拉低CE,使芯片开始发送
}
//
/*************************************************************
                           主函数

*************************************************************/
void main(void)
{
unsigned char DATA_for_R[10];

unsigned char a,b,c,d,e,f,g,h,i,j;
unsigned char k;
ADCON1 = ADCON1 | 0x0f;//关闭模拟IO
TRISA = 0x00;//A口为输出
TRISAbits.TRISA5=0;//LED点亮
Init_IOforNRF2401();//初始化端口
NRF2401_Init();//按表格配置NRF2401
//TRISB=0xff;
        while(1)
   {
//NRF2401_Init();//按表格配置NRF2401
if(PORTBbits.RB2==1)
     {
             LATAbits.LATA5=0;
        NRF2401_DataSerialRead(DATA_for_R,10);
        a=DATA_for_R[0];
        b=DATA_for_R[1];
        c=DATA_for_R[2];
        d=DATA_for_R[3];
        e=DATA_for_R[4];
        f=DATA_for_R[5];
        g=DATA_for_R[6];
        h=DATA_for_R[7];
        i=DATA_for_R[8];
        j=DATA_for_R[9];  
for(k=0;k<10;k++)
    {
      if(DATA_for_R[k]!=Dat[k])
            {
              LATAbits.LATA5=0;
              while(1);
            }
    }
   
     }
else
    {
      LATAbits.LATA5=1;
    }

  }
}

出0入0汤圆

 楼主| 发表于 2009-8-15 17:18:50 | 显示全部楼层
感谢楼上的热心帮助,你这个是shockburst mode,我想要的是direct mode。
目前直接模式摸不到头绪,而且基本看不到用这个direct mode 来进行射频收发的

而且我对无线通信的直接模式基本不了解,有那位比较了解能进行一些说明吗?
比如说射频芯片是如何确定帧头是有效帧头?
目前2401的帧头是01010101或者10101010,根据第一个地址的第一位来确定的,我配置成直接模式后,用示波器看DATA脚,这样的帧头很多,所以现在不知道到底哪里是有效数据开始位。

还有直接模式的发送时序是不是一定要1us(1Mbps)发送一位?

出0入0汤圆

发表于 2011-2-11 15:00:21 | 显示全部楼层
回复【3楼】qusongsong
-----------------------------------------------------------------------

虽然是很长时间过去了,我还是撞撞运气吧,请问一下,你的直接模式调通了吗?我也不太了解直接模式,能指点一下吗?它的前端码,地址,奇偶校验,这些都要和数据一起发过去吗?CRC是怎样弄得?谢谢!!!

出0入0汤圆

发表于 2011-2-12 23:06:26 | 显示全部楼层
所谓直接模式就是非应答方式,减少了等待应答的时间,操作基本类似,只管使劲发送就是了,但可靠性不能保证
要软件自己来认证

出0入0汤圆

发表于 2011-11-10 21:36:58 | 显示全部楼层
你这里说的直接模式是不是不用自动应答的意思?

51的例程其中一句要改成SPI_RW_Reg(WRITE_REG + EN_AA, 0x00);// 不使能通道0自动应答。

网上的51程序大多都是发送方发送-等应答-(自动重发)-触发中断。可是这样的流程就已经把接收方给牵涉进来了,就是说一定要接收方正确收到数据并且回送应答信号之后发送方才能触发中断,结束一次完整的发送。可是这跟我们的初衷不相符,我们想单独调试发送,完全抛开接收,这样就要去配置一些参数来取消自动应答,取消自动重发,让发送方达到发出数据就算成功的目的。

很多程序这里的数据是0x01,意思是使能。如果你是这个意思的话,我这里有份资料我也在学习中,不知你用不用得上。(上面那段话引自网络)
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-4-19 18:25

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

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