集成电路技术分享

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
12
返回列表 发新帖
楼主: 小舍YZ

nRF24L01无线模块在单片机与FPGA上的应用

[复制链接]
 楼主| 小舍YZ 发表于 2017-3-21 15:09:13 | 显示全部楼层
  NRF24L01接收的初始化以及接收时序

1 void init_NRF24L01_receive(void)

2 {

3     delay(30);

4      CE=0;    // chip enable

5      CSN=1;   // Spi disable

6      SCK=0;   // Spi clock line init high

7     delay(30);

8     SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    // 写本地地址   

9     SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址

10     SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);      //  频道0自动    ACK应答允许   

11     SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  //  允许接收地址只有频道0,如果需要多频道可以参考Page21  

12     SPI_RW_Reg(WRITE_REG + RF_CH, 40);        //   设置信道工作为2.4GHZ,收发必须一致

13     SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节

14     SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);           //设置发射速率为1MHZ,发射功率为最大值0dB   

15     SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);            // IRQ收发完成中断响应,16位CRC,主接受

16     CE=1;

17     delay(40);   

18 }

19

20

21 /******************************************************************************************************/

22 /*函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)

23 /*功能:数据读取后放如rx_buf接收缓冲区中

24 /******************************************************************************************************/

25 unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)

26 {

27     unsigned char revale=0;

28     sta=SPI_Read(STATUS);    // 读取状态寄存其来判断数据接收状况

29     if(RX_DR)                // 判断是否接收到数据

30     {

31         CE = 0;             //SPI使能

32         SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// read receive payload from RX_FIFO buffer

33         revale =1;            //读取数据完成标志

34     }

35     SPI_RW_Reg(WRITE_REG+STATUS,0xff);

36     return revale;

37 }

下面总结一下NRF24L01在FPGA的应用。
 楼主| 小舍YZ 发表于 2017-3-21 15:09:30 | 显示全部楼层
  由于FPGA自带SPI硬件,只需要在SOPC Bulider中添加SPI模块即可,在顶层图中我们就可以看到图1.4,另外,我们再添加两个IO口,这样我们就不必再模拟SPI方式,在FPGA中,有一个很好的API函数alt_avalon_spi_command();其函数原型为:



1 int alt_avalon_spi_command(alt_u32base,alt_u32slave,
2      alt_u32write_length,
3      constalt_u8*wdata,
4      alt_u32read_length,
5      alt_u8*read_data,
6      alt_u32flags)
 楼主| 小舍YZ 发表于 2017-3-21 15:09:47 | 显示全部楼层
该函数执行以下功能:
    1、 SPI 从机片选信号有效(拉低) ;
    2、 从 wdata 指针读取数据,通过 SPI 接口传输总共 write_length 字节的数据,丢弃 MISO接口输入的数据;
    3、 读 read_length 个字节的数据,存储到 read_data 指针指向的地址。读传输过程中 MOSI 被置为 0;
    4、 撤销 SPI 从机片选信号(拉高)。
    头文件,该头文件定义了 SPI 核的寄存器映射和访问硬件可用的一些特征常量。

这个函数的最大缺点就是不可以在中断中使用,但这并不影响对它的使用。NRF24L01在单片机和FPGA上的应用的本质是一样的,主要区别就是对上面的A、B  SPI方式进行改写。
 楼主| 小舍YZ 发表于 2017-3-21 15:11:14 | 显示全部楼层
A   就是用alt_avalon_spi_command();代替,是不是很方便呢。:-D

B  以SPI方式对寄存器的操作

1 /*********************************************************************

2 ** 函数名称: void SPI_RW_Reg(unsigned char reg, unsigned char value)()

3 ** 函数功能: 访问无线模块寄存器,并也对其写数值控制

4 ** 参数:2个,第一个为寄存器地址,第二个为向寄存器写的数值

5 *********************************************************************/

6 void SPI_RW_Reg ( unsigned char reg, unsigned char value )

7 {

8     alt_avalon_spi_command ( SPI_BASE,0,1,®,0,NULL,1 );               // select register

9     alt_avalon_spi_command ( SPI_BASE,0,1,&value,0,NULL,0 );

10 }

11

12 /*********************************************************************

13 ** 函数名称: void SPI_Write_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes)

14 ** 函数功能: 访问寄存器,并向其写入bytes字节的数值

15 ** 参数:3个,寄存器地址,数据、长度

16 *********************************************************************/

17 void SPI_Write_Buf ( unsigned char reg, unsigned char *pBuf, unsigned char bytes )

18 {

19     alt_avalon_spi_command ( SPI_BASE,0,1,®,0,NULL,1 );

20     alt_avalon_spi_command ( SPI_BASE,0,bytes,pBuf,0,NULL,0 );

21 }

22 /********************************************************************

23 ** 函数名称: unsigned char SPI_Read(unsigned char reg)

24 ** 函数功能: 访问寄存器地址,并返回该寄存器的数值

25 ** 参数:寄存器地址

26 *********************************************************************/

27 unsigned char SPI_Read ( unsigned char reg )

28 {

29     unsigned char reg_val;

30     alt_avalon_spi_command ( SPI_BASE,0,1,®,0,NULL,1 );

31     alt_avalon_spi_command ( SPI_BASE,0,0,NULL,1,®_val,0 );

32     return ( reg_val );

33 }

34 /*

35 *********************************************************************

36 ** 函数名称: void SPI_Read_Buf(unsigned char reg, unsigned char *pBuf, unsigned char uchars)

37 ** 函数功能: 访问寄存器,并从其读出bytes字节的数值

38 ** 参数:3个,寄存器地址,数据、长度

39 *********************************************************************

40 */

41 void SPI_Read_Buf ( unsigned char reg, unsigned char *pBuf, unsigned char uchars )

42 {

43     alt_avalon_spi_command ( SPI_BASE,0,1,®,0,NULL,1 );

44     alt_avalon_spi_command ( SPI_BASE,0,0,NULL,uchars,pBuf,0 );

45 }
 楼主| 小舍YZ 发表于 2017-3-21 15:11:42 | 显示全部楼层
  跟单片机相比,是不是觉得看得清晰点呢。这就是这个函数的方便之处了。有一点要注意一下,这个函数的最后一个参数的作用,以前没注意,走过一段弯路,它的作用就是相当于上面单片机中的CSN信号,如果需要对SPI从器件进行连续访问,则不释放该信号可以提高访问速度。

  好了,差不多就总结到这里了。无线模块的应用很广泛,可以用作无线遥控器、数据的无线烧写等用途。
大鹏 发表于 2017-3-21 17:58:56 | 显示全部楼层
厉害了,楼主!
zxopenljx 发表于 2020-7-9 09:27:43 | 显示全部楼层
nRF24L01无线模块在单片机与FPGA上的应用
zxopenljx 发表于 2023-10-27 17:44:12 | 显示全部楼层
nRF24L01无线模块在单片机与FPGA上的应用
您需要登录后才可以回帖 登录 | 我要注册

本版积分规则

关闭

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

QQ|小黑屋|手机版|Archiver|集成电路技术分享 ( 京ICP备20003123号-1 )

GMT+8, 2024-6-23 10:20 , Processed in 0.076439 second(s), 17 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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