中国自动化学会专家咨询工作委员会指定宣传媒体
免费注册 登录 广告服务 | 客服中心
您现在所在的是:

单片机论坛

抖音 德嘉 泓格论坛 FLIR红外热像论坛
工控论坛首页 单片机论坛 → 浏览主题: 2401学习笔记
发表新帖 回复该主题
回帖:2个,阅读:1478 [上一页] [1] [下一页]
* 帖子主题:

2401学习笔记

分享到
912
sfmcu
文章数:44
年度积分:50
历史总积分:912
注册时间:2006/8/22
发站内信
08年优秀博客奖
发表于:2010/12/30 23:52:49
#0楼

图
图
ce:使能发射或接收;
csn,sck,mosi,miso:spi引脚端,微处理器可通过此引脚配置nrf24l01:
irq:中断;
vdd:电源输入端;
vss:电源地:
xc2,xc1:晶体振荡器引脚;
vdd_pa:为功率放大器供电,输出为1.8 v;
ant1,ant2:天线接口;
iref:参考电流输入

使用io[/b]口模拟spi[/b],以龙丘科技的无线模块为例,使用m[/b]口模拟spi[/b]可如下定义[/b]
#define    nrfirq    ptm_ptm0[/b]
#define    nrfce      ptm_ptm1[/b]
#define  nrfmiso         ptm_ptm2[/b]
#define    nrfcsn   ptm_ptm3[/b]
#define  nrfmosi         ptm_ptm4[/b]
#define    nrfsck    ptm_ptm5[/b]
图
由图可知,发送时高位在前,低位在后,每写一个bit,返回一个状态字位,每次写操作都可读回一个完整的状态字。
以下是读回的状态字
status(地址:0x07)
保留
rx_dr
tx_ds
max_rt
rx_p_no


tx_full
rx_dr: 接收数据准备好,接收缓冲区有新的数据到达时被置为1,向该位写1可清除该位
tx_ds: 缓冲区数据被发送完后被置为1,如果自动应答启用的话,只有在对方应答到达后才会置1,向该位写1可清除该位
max_rt: 若没有收到对方确认,24l01会自动超时重传,当到达最大重传次数后,该位被置1,向该位写1可清除该位。若不清除该位则无法进一步通信。
rx_p_no: 3bit,表示正在读取缓冲区数据载荷的数据管道编号。000~101:数据管道编号。
110:没有使用
111:接收缓冲区空
ps[/b]:接收到新数据,数据发送完毕,重传到达最大次数都会引起中断,通过读取状态字可查询中断事件。[/b]
中断由irq[/b]引脚低电平触发。[/b]
图
spi写模式
/********************************************************************
spi读写函数
写入一个字节并返回一个字节
ch:需要写入的字节
*********************************************************************/
unsigned char spi_byte_rw(unsigned char ch)
{
 unsigned char i;
 for(i=1;i
 {
   if(ch&0x80)//如果ch最高位为1
   nrfmosi=1;
   else
   nrfmosi=0;
   nrfsck=1;//时钟置高
   ch左移一位
   _asm(nop);
   _asm(nop);
   nrfsck=0;//时钟置低
   ch|=nrfmiso;
 }
 return(ch);
}
解释:
1、  该函数作用为一次spi数据交换,将ch中一个字节数据按照高位在前低位在后的顺序串行发送,每发送一个bit都读回一个bit,8个比特发送完毕,同时也和24l01完成一次数据交换。
2、  该函数是spi通信的基本函数
3、  注意spi通信中,可以一次读取或写入多个字节,顺序为低字节在前,高字节在后,每个字节是高位在前,低位在后。
4、  参考spi时序图,可见,上升沿写入1个bit,下降沿读入一个bit。
5、  该spi通信函数只涉及一个字节的读写,没有涉及cs信号线。
spi_byte_rw()函数应用举例,一次写入多个字节
/************************************************************************************************
函数:byte spi_write_buf(byte reg, byte *pbuf, byte len)
功能: 用于写数据:为寄存器地址,pbuf:为待写入数据地址,len:写入数据的个数
************************************************************************************************/
byte spi_write_buf(byte reg, byte *pbuf, byte len)
{
        byte status,cnt;
        nrfcsn = 0;            //spi使能      
        status = spi_byte_rw(reg);   //第一个字节返回状态字
        for(cnt=0; cnt
        spi_byte_rw(*pbuf++);
        nrfcsn = 1;           //关闭spi
        return(status);    //
}
ps:该函数完成多个字节的写入,返回状态字
本函数举例:
例:我们要设置本机地址,24l01的地址为5个字节,假设地址放在一个5字节的数组中
byte const tx_address[tx_adr_width]= {0x34,0x43,0x10,0x10,0x01};   //本地地址
写寄存器的指令字为001a aaaa,   aaaaa用于表示写入的寄存器地址,各个寄存器地址可查阅数据手册
tx_addr寄存器在24l01中的地址为00010000,那么完整的指令字应该为00110000,可用如下定义和调用方法
//***********************nrf24l01指令字*******************************************************
#define read_reg        0x00        // 读寄存器指令
#define write_reg       0x20         // [/b]写寄存器指令[/b]
#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  // [/b]发送地址寄存器[/b]
#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栈入栈出状态寄存器设置
可用以下语句调用
spi_write_buf(write_reg + tx_addr, tx_address, tx_adr_width);    // 写本地地址



24l01被设置为接收模式后,可通过6个不同的数据通道(data pipe)接收数据。每个数据通道都有一个唯一的地址但是各数据通道的频率是相同的。这意味着可以有6个被配置成发送状态的nrf24l01可以和一个配置成接收状态的nrf24l01通信,并且接收方可以区分。数据通道0有一个唯一的40bit的可设置的地址。其余的通道1到通道5则地址前32位相同,而后8位不同。所有的数据通道都可以实现enhanced shockburst模式。
nrf24l01使用数据通道的地址对接收的包进行确认。这意味着24l01在返回ack的时候使用相同的地址。在发送端,数据通道0被用来接收确认信息,因此通道0的地址必须等于发送地址,这样才能收到确认信息。
当一个24l01发送结束后,它会打开接收器并等待确认。如果没有收到确认,则重发,直到收到确认。当重发超过一定次数则发出中断并改变状态寄存器。重发次数的限制在setup_retr_arc寄存器中设置。
无论何时收到确认,都会认为上一个数据包发送成功,这个数据包将被从发送缓冲区清除,并且把tx_ds irq置为高。
每次开始spi写,读回来的都是状态字。
射频收发工作在2.4~2.4835g
收发共用天线接口
gfsk调制
250k,1m,2m的空中速率
发射输出功率最高0dbm,即1mw
6路1对6星型网络(使用6个data pipe)
增强型shockburst包格式
前置域1byte
地址域3-5byte
包控制域9bit
载荷0-32字节
crc1-2字节
地址域是接收机地址
包控制域
载荷长度6bit
pid2bit
no_ack1bit
载荷长度6bit说明最多32字节
pid用于包编号,用于确定是重发包还是新包
no_ack用于表示是否自动应答,如为1则表示无需自动应答
自动应答的延时和重发次数是可编程的。
/********************************************************************************/
/*函数:void setrx_mode(void)
/*功能:数据接收配置
/********************************************************************************/
void setrx_mode(void)
{
        nrfce=0;  
        spi_rw_reg(write_reg + config, 0x0f);                  // irq收发完成中断响应,16位crc ,主接收  
        nrfce = 1;
        dly_10us(15);                     //old is 130
}
将00001111写入config寄存器
以下是config寄存器说明
保留,为0
mask_rx_dr
mask_tx_ds
mask_max_rt
en_crc
crco
pwr_up
prim_rx

mask_rx_dr  和mask_tx_ds和mask_max_rt 主要用于设置status寄存器中的这三位表示的事件发生时 是否通过irq引脚来反映,1,不反映在irq上,0反映在irq上。
en_crc:1,启用crc校验,0不启用
crco:0:1个字节crc,1:两个字节crc
pwr_up:1:powerup  0:powerdown
prim_rx:1:prx  0:ptx

24l01的工作模式和寄存器及io口的关系如下
图
ce引脚的作用
图
增强型shockburst模式时序图
一个esb(enhanced shockburst)周期,发送一个字节连带收到ack大约339us
从powerdown状态需要先进入standyby状态,该状态转换需要1.5ms延迟,从standyby状态进入rx/tx状态,需要130us
置高ce维持最少10us,启动enhanced shockburst发射
图
直接传送模式发送
图
1.config寄存器:地址00
保留,为0
mask_rx_dr
mask_tx_ds
mask_max_rt
en_crc
crco
pwr_up
prim_rx
mask_rx_dr  和mask_tx_ds和mask_max_rt 主要用于设置status寄存器中的这三位表示的事件发生时 是否通过irq引脚来反映,1,不反映在irq上,0反映在irq上。
en_crc:1,启用crc校验,0不启用
crco:0:1个字节crc,1:两个字节crc
pwr_up:1:powerup  0:powerdown
prim_rx:1:prx  0:ptx

2.en_aa寄存器:地址01
保留,0
保留,0
enaa_p5
enaa_p4
enaa_p3
enaa_p2
enaa_p1
enaa_p0
是否启用各data pipe的自动应答功能,1启用,0,不启用,复位默认为启用

3. en_rxaddr寄存器:地址02
保留,0
保留,0
erx _p5
erx _p4
erx _p3
erx _p2
erx _p1
erx _p0
是否启用各data pipe, 1启用,0,不启用,复位为00000011,即默认启用datapipe1和datapipe 0

4. setup_aw寄存器:地址03
保留,0
保留,0
保留,0
保留,0
保留,0
保留,0
aw1
aw0
地址宽度,所有data pipe 都一样
aw1,aw0=00,非法,01,3字节地址,10,4字节地址,11,5字节地址,默认为11,即5字节地址

5. setup_retr寄存器:地址04(设置自动重传参数)
ard(复位为0000)
arc(复位为0011)
ard=0000,重传间隔为250+86us
    0001,重传间隔为500+86us
…………………………….
1111, 重传间隔为4000+86us
arc=0000,禁止自动重传
    0001,重传1次
    ……………………………..
    1111,重传15次

6. rf_ch寄存器:地址0x05,设置频道
保留,0
rf_ch
7个bit用于设置通信频道,共126个频道,复位为00000010,频道2

7. rf_setup寄存器:地址0x06
保留,0
保留,0
保留,0
pll_lock
rf_dr
rf_pwr
lna_hcurr
pll_lock:
rf_dr:速率,0:1m   1:2m
rf_pwr:00  18dbm
01      12dbm
10   6dbm
11   0dbm

8. status寄存器:地址0x07
保留 0
rx_dr
tx_ds
max_rt
rx_p_no


tx_full
rx_dr: 接收数据准备好,接收缓冲区有新的数据到达时被置为1,向该位写1可清除该位
tx_ds: 缓冲区数据被发送完后被置为1,如果自动应答启用的话,只有在对方应答到达后才会置1,向该位写1可清除该位
max_rt: 若没有收到对方确认,24l01会自动超时重传,当到达最大重传次数后,该位被置1,向该位写1可清除该位。若不清除该位则无法进一步通信。
rx_p_no: 3bit,表示正在读取缓冲区数据载荷的数据管道编号。000~101:数据管道编号。
110:没有使用
111:接收缓冲区空
ps:接收到新数据,数据发送完毕,重传到达最大次数都会引起中断,通过读取状态字可查询中断事件。
中断由irq引脚低电平触发。

9. observe_tx寄存器:地址0x08(发送观察寄存器,用于观察发送状态)
plos_cnt
arc_cnt
plos_cnt:丢包计数器,最大到15,写rf_ch寄存器可清除计数值
arc_cnt:重发次数计数

10. cd寄存器:地址0x09(载波检测寄存器)
保留 0
保留 0
保留 0
保留 0
保留 0
保留 0
保留 0
cd
cd:检测到载波则置1,否则为0

11. rx_addr_p0寄存器:地址0x0a(data pipe 0接收地址)
共5个字节,低字节在前,高字节在后默认为0xe7e7e7e7e7
12. rx_addr_p1寄存器:地址0x0b(data pipe 1接收地址)
共5个字节,低字节在前,高字节在后默认为0xc2c2c2c2c2
13. rx_addr_p2寄存器:地址0x0c(data pipe 2接收地址)
共5个字节,低字节在前,高字节在后0xc2c2c2c2c3
14. rx_addr_p3寄存器:地址0x0d(data pipe 3接收地址)
共5个字节,低字节在前,高字节在后0xc2c2c2c2c4
15. rx_addr_p4寄存器:地址0x0e(data pipe 4接收地址)
共5个字节,低字节在前,高字节在后0xc2c2c2c2c5
16. rx_addr_p5寄存器:地址0x0f(data pipe 5接收地址)
共5个字节,低字节在前,高字节在后0xc2c2c2c2c6
17. tx_addr寄存器:地址0x10(发送地址寄存器,对发送端而言,相当于源地址,也是接收端发回确认的目的地址)
共5个字节,默认为0xe7e7e7e7e7
18. rx_pw_p0寄存器:地址0x11
保留 0
保留 0
rx_pw_p0
rx_pw_p0:data pipe0 的接收数据载荷长度
         0:非法
         1:1个字节
       …………………..
         32:32个字节
19. rx_pw_p1寄存器:地址0x12
保留 0
保留 0
rx_pw_p1
rx_pw_p1:data pipe1 的接收数据载荷长度
         0:非法
         1:1个字节
       …………………..
         32:32个字节
20. rx_pw_p2寄存器:地址0x13
保留 0
保留 0
rx_pw_p2
rx_pw_p2:data pipe2 的接收数据载荷长度
         0:非法
         1:1个字节
       …………………..
         32:32个字节
21. rx_pw_p3寄存器:地址0x14
保留 0
保留 0
rx_pw_p3
rx_pw_p3:data pipe3 的接收数据载荷长度
         0:非法
         1:1个字节
       …………………..
         32:32个字节
22. rx_pw_p4寄存器:地址0x15
保留 0
保留 0
rx_pw_p4
rx_pw_p4:data pipe4 的接收数据载荷长度
         0:非法
         1:1个字节
       …………………..
         32:32个字节
23. rx_pw_p5寄存器:地址0x16
保留 0
保留 0
rx_pw_p5
rx_pw_p5:data pipe5 的接收数据载荷长度
         0:非法
         1:1个字节
       …………………..
         32:32个字节
24. fifo_status寄存器:地址0x17
保留 0
tx_reuse
tx_full
tx_empty
保留 0
保留 0
rx_full
rx_empty
tx_reuse:

enhanced shockburst™ 模式下发送数据流程
1.         配置config寄存器,将prim_rx置为0,表示发送模式
2.         当需要发送数据时,首先需要配置地址tx_addr,这个地址应该是接收端地址,即应该是接收端6个data pipe地址中的一个即可保证对方收到。如果要使用自动应答,当对方进行自动应答时也会使用这个地址,应答消息由发送端的datapipe0接收,所以发送的datapipe0的地址应等于tx_addr,若需要自动应答则。(若是和上一次发送是相同地址,则可不用重写地址)
3.         配置tx_pld,将需要发送的数据送入nrf24l01,通过spi连续写入数据载荷时,nrf24l01将自动对字节数计数。(数据载荷必须在cs为低的时候连续写入)
4.         将ce置高并维持最少10us,这个脉冲将启动shockburst发送
5.         nrf24l01:
a)         打开射频
b)         启动晶振
c)         数据打包
d)         发送
6.         如果启动了自动应答(且重传次数未达到最大值),nrf24l01将自动转入接收状态。若在规定时间内收到了应答包,则这是一次成功的发送,tx fifo中的数据被清除,同时置高status寄存器中的tx_ds位。如果在规定时间内未收到应答包则自动重传(当启用自动重传时,由setup_retr寄存器中的arc位指定重传次数)。当重传次数到达最大值依然没有收到应答,则status寄存器中的max_rt被置高,tx fifo缓冲区中的数据并不被移除。max_rt 或 tx_ds被置高都会在irq引脚上引起中断(低电平有效,重写status寄存器中的对应位可清除)。在到达最大重传次数并引发中断后,在没有清除max_rt之前,任何数据都不能发送。每次发生max_rt 中断,plos_cnt计数器都会加1,用于统计丢包数。
7.         ce置低以后,设备进入standby_i状态。否则tx fifo缓冲区中的下一个数据载荷将被发送。如果数据缓冲区空,而ce仍然为高,设备将进入standby-ii模式。
如果设备处于standby-ii模式,当ce置低后,设备将进入standby-i模式。
(standby模式可减少电流的消耗,在该模式下,spi通信仍然可以完成)
图
enhanced shockburst™ 模式下接收数据流程
1.         设置config寄存器中的prim_rx为1,且置ce为高
2.         130us之后,nrf24l01开始监视射频信号
3.         当合法的包被接收到(地址匹配),数据被存储到rx-fifo缓冲区中,status寄存器中的rx_dr被置高,irq引脚同时发出中断信号(如果未屏蔽该信号)。status寄存器中的rx_p_no指示这个应该接收该数据的data pipe号。
4.         如果自动应答启用的话,一个应答信号将被发出
5.         mcu将ce置为低将进入standby-i模式
6.         mcu可通过spi读出接收到的数据

----------------------------------------------
此篇文章从博客转发
原文地址: Http://blog.gkong.com/more.asp?id=131817&Name=sfmcu
87
gkongman
文章数:-5
年度积分:-120
历史总积分:87
注册时间:2010/12/30
发站内信
发表于:2011/1/13 16:24:04
#1楼
此楼内容不符合板块规定,不予显示! 查看原帖内容>>
17521
ahljj
文章数:3386
年度积分:233
历史总积分:17521
注册时间:2002/3/23
发站内信
发表于:2012/3/23 15:34:47
#2楼
看一看....
工控学堂推荐视频:

关于我们 | 联系我们 | 广告服务 | 本站动态 | 友情链接 | 法律声明 | 非法和不良信息举报

工控网客服热线:0755-86369299
版权所有 工控网 Copyright©2024 Gkong.com, All Rights Reserved

62.4004