原帖地址:http://www.dowellbbs.com/forum.php?mod=viewthread&tid=570&extra=page%3D1
程序下载地址:http://www.dowellbbs.com/forum.php?mod=viewthread&tid=571&extra=page%3D1
接前一篇文章
可以看到它的寄存器偏移是0x01,这里说明一下,如果想要进行写操作那么操作的寄存器地址是WRITE_REG + EN_AA,也就是EN_AA加上写指令的基地址,若是读操作那么是READ_REG + EN_AA,也就是EN_AA加上读指令的基地址。
我们看看EN_AA这个寄存器的功能是什么。它的位为8位初始化的值为00111111即0x3f,每个位的功能上表已经很详细了。 这个送的数据是0x01,那么表示什么意思呢?意思是允许数据通道0自动应答,而其他的通道禁止,明白了吧。其他的都是这个样子滴。
这是NRF24L01设置发射模式时的初始化过程。下面我们看看怎么用NRF24L01进行无线数据发射传输。
我们从主函数main开始。
主函数很简单,我们为您提供了两个模式的发射方式:手动发射(按键控制)和自动发射(每隔一段时间发送一次数据)。
这是模式1,该模式为自动发射。可以看到主函数调用的就是模式1,对于模式0手动方式,大家把主函数的Mode1改为Mode0就可以验证了。详细请看程序源码。
在Mode1()这个函数中我们看看是怎么样的一个操作顺序。先延时1500ms左右,然后装载数据到NRF24L01,LED的操作就很简单了只是一个提示的作用,最后再清除NRF24L01的状态标志位,为下一次发送数据准备。大家要了解数据的发送是这个样子的。
我们来看看NRF24L01_TxPacket()这个函数。
注释的部分是装载接收端的地址,也就是为应答信号服务的,由于在初始化的时候已经初始化过了,所以这里可以不需要,但是当您使用NRF24L01跟多的功能时,如使用了多通道通信,需要应答时,这句就有用了,需要设置为对应接收通道的地址才能收到应答信号。这些功能大家知道就可以了,本教程也是让大家会用NRF24L01,后续还是靠大家自行努力了。
接着是装载数据了,WR_TX_PLOAD是装载数据的命令地址,tx_buf是接收的数据指针,TX_PLOAD_WIDTH是指要发送的数据字节数。定义如下:
注意TX_PLOAD_WIDTH最大为32字节,不得超过此数。
数据装载完成后需要的是发送命令了。
这句就是设置了为发送的状态,在CE被拉高的时间里自动启动发送。那么紧接着CE=1就是此目的了。
上面的三句用于发送完成判断以及中断状态的清除,为下次发送准备。
CONFIG为什么设置数据为0x5e(0101 1110)就是发送呢,那么看下这个寄存器各个位的功能就明白了。
看看最低位的功能:1 接收模式 0 发射模式,这明白了吧。其他位大家自己看看是什么功能吧。
这样一个完整的发射过程就完成了,刚才说了Mode1()是循环发射模式,一次完成后就会进入下一次发射了。
那么到这里我们的项目任务算是完成了一半了,还剩下另一半了。
看了发射模式之后,我们再来看接收模式就不会很困难了。
接收模式的配置初始化为:
1. 设置TX节点的地址,也就是发射地址,接收端需与这个地址相同,否则接收不到数据。在接收模式中此配置可不用。
寄存器为:
TX_ADDR
2. 设置RX节点的地址,也就是接收时的地址,如果是在发射模式下那么功能是为自动应答服务的(AUTO ACK)。
寄存器为:
RX_ADDR_P0
3. 允许AUTO ACK功能,意思是发送数据后都会等待接收端的应答信号,目的是保证数据正确发送。
寄存器为:
EN_AA
4. 设置允许的接收通道,总共有6个通道,我们只使用通道0,其他通道的功能应用大家熟悉了NRF24L01之后尝试吧。
寄存器为:
EN_RXADDR
5. 配置自动重发次数。在接收模式中此配置可不用。
寄存器为:
SETUP_RETR
6. 选择通信的频率。
寄存器为:
RF_CH
7. 设置接收通道0的接收数据有效宽度,与第四步对应。
寄存器为:
RX_PW_P0
8. 配置发射的参数,主要为低噪放大器增益、发射的功率、无线传输的速率。
寄存器为:
RF_SETUP
9.
配置收发状态(这时配置为接收模式),CRC
校验模式以及收发状态响应方式。发射模式和接收模式在初始化时只要这里设置为接收模式即可,也只有这里不一样,其他配置都是一样的(把配置都设置成一样的)。
寄存器为:CONFIG
10. 清除NRF24L01的指定通道中断状态标志,注意发送和接收这部分清除的通道的选择必须一致。
寄存器为:
STATUS
为此操作起来就更加简单了。从上面的初始化方式我们可以看到接收与发射的设置基本一致,只是接收模式中
CONFIG
寄存器的最低位变成高位即可,另外设置TX地址和设置重发次数,对于接收时也是无关紧要的,所以设置不设置我们可不比理会,当然直接删除也是没问题的。在接收模式中仍然使用发射模式下的初始化函数Init_NRF24L01(),我们的例程就是如此。
前面说到发射与接收模式的不同就在于CONFIG这个寄存器的设置不同,发射模式这个寄存器的最后一位需要置0,那么接收就得置1,所以在判断接收前把这个位设置一下不就可以了。
我们写一个函数来实现这个功能:
在接收模式中我们最需要注意的就是这个接收模式的设置了。向CONFIG些0x3f就可以把最后一位设置为1了,且选择接收到数据时IRQ引脚变低,这样就成了接收模式了。
我们也从主函数出发,看看是怎么操作的。
前面的初始化我们需要了解的是InitUSART()这个函数,我们项目最开始的要求有一项是接收端接收到的数据需要发送到PC进行查看,InitUSART()这个函数就是初始化串口通信的。看它的原型:
这个初始化就不多说了,对于不同的波特率使用
这两个宏定义就行了,FOSC表示当前系统时钟,BAUD表示需要的波特率。注意使用的是定时器1而不是定时器0。
串口发送数据的函数是Rx_Byte()源码如下:
只要按照Rx_Byte(Dat)这样调用就能把Dat这个数据发送到PC了,PC需要用串口助手来查看数据,我们使用的STC-ISP下载软件即可使用,设置如下:
选择到串口助手界面,在下面设置COM口和波特率,其他默认就可以了。点击
这个按钮就可进入串口助手模式了。
我们接着看主函数的代码,LED=1是熄灭LED的,如果接收不到数据那么是长灭的状态,接收到数据且数据完全正确后才被点亮一段时间(闪烁一下的效果)用于提示。
紧接着是
这个if条件语句,它就是查询判断NRF24L01的接收状态的。我们来看着这个被调用的函数:
这句用来判断是否有数据的接收,前面我们配置中开启了接收中断,也就是说当有数据接收后,这个引脚会变成低电平,由NRF24L01输出拉低的。这样判断相对于判断NRF24L01内部的状态效率会更高。
是读取NRF24L01的状态,目的是判断是否有数据接收。为什么要加上这句,还要判断内部状态呢。答案是:这句不是必须的,但如果你想确实保证正确的数据接收状态也未尝不可(相当于一个保险,O(∩_∩)O~),当然了,删除也是可以的,
但是这个判断
24L01
内部状态和判断中断引脚的方法必须保留一个,大家知道有这样的方法就行了
是STATUS的宏定义,是状态寄存器的地址。
SPI_Read()的源码为:
前面说了所有的寄存器操作都是先设置寄存器地址,然后在写(或读)数据或命令()状态。那么这里呢SPI_Read()这个函数就不说了。这里值得一提的是
这个调用,传入的实参是
,有很多人不明白这个。这里呢简单说一下,可以看到对于读来说这个数据是没有用的,所以可以是任何的数据。然而习惯上都爱使用0xff,希望大家慢慢能够明白。
在NRF24L01_RxPacket()这个函数中还有个特别的变量sta,它的声明为:
可以看到这个使用了位操作,目的是什么呢?这样可以使位操作变得非常简单,对于判断状态是很有用的。
我们来看STATUS这个寄存器的意义:
可以看到对于接收我们需要判断RX_DR这个位是否为1,为1就表示有数据了。那么用这个定义
就可以直接访问sta这个变量的第七位了,很方便,也不用使用位运算来实现了。
当查询到有数据了就会调用
读出数据放到rx_buf中也就是主函数的RxBuf[]中了(rx_buf指向的地址为RxBuf[])。这样就完成了数据的读出操作,下面是置位
这个接收完成且成功标志位。
完成接收后不要忘记状态的清除操作,为下次接收准备。
在NRF24L01_RxPacket()这个函数中的最后就是返回ReceiveComplete_Flag这个变量了。在主函数中用于判断是否有数据接收成功。
若接收数据成功了,那么我们接着看主函数。在项目的开始我们要求发送到PC端进行接收数据的查看,为此我们用下面的代码实现:
32次循环依次把接收到的数据通过Rx_Byte()这个函数由串口发送到PC。
要求中还有一个是要求是检验接收的数据是否与发送端完全一样,这个怎么完成呢?思路是这样的:我们也定义一个数组CheckBuf[],这个数组中的数据与发送端发送的数组数据完全一样,然后把接收数组RxBuf[]中的数据与CheckBuf[]一一对比即可达到检验的目的了。接收和发送端的数组数据如下图:
发送端数据:
接收端用于检测的数据:
对于这个检验代码如下:
以上的设计思路为:在向PC每发送一个字节的数据,都会检测一次RxBuf[]接收缓冲中的数据,如果相等那么Right_Count正确个数计数器会自加一,32个数据向PC端发送完成后,检验比较也就完成了,如果相等那么Right_Count将会等于32。然后再判断Right_Count是否大于等于32(特别建议:如果在判断一个变量是否等于某个数时,尽量使用大于等于或者小于等于判断的方法,可防止出错,是对于程序安全稳定来说的),就可知道接收的数据是否通过检测没有错误了。如果完全相等,那么会有LED=0执行,LED被点亮用于提示校验成功。
好啦到这里就讲解完成了,大家就仔细研究研究吧。多玩玩程序。
PC端接收的数据如下:
可以看到数据也是完全正确的
经过我们的下载测试,LED指示也是完全正确的。大家可以把这个程序下载来看看了。
到这里对于这个小项目的要求就都完成了。
您如果成功了是不是很开心呢,O(∩_∩)O!
最后提示,若您是自己搭建的,那线的连接不要错了哦!若您使用我们的板子有任何问题,请您及时联系我们。
之后我们还会推出更多关于NRF24L01有趣的应用的,敬请期待!这算是个入门的教程,大家多多支持。我们水平也是有限的不可能面面俱到,有问题或者错误请联系我们,感激不尽。