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的应用。
由于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)
该函数执行以下功能:
1、 SPI 从机片选信号有效(拉低) ;
2、 从 wdata 指针读取数据,通过 SPI 接口传输总共 write_length 字节的数据,丢弃 MISO接口输入的数据;
3、 读 read_length 个字节的数据,存储到 read_data 指针指向的地址。读传输过程中 MOSI 被置为 0;
4、 撤销 SPI 从机片选信号(拉高)。
头文件,该头文件定义了 SPI 核的寄存器映射和访问硬件可用的一些特征常量。
这个函数的最大缺点就是不可以在中断中使用,但这并不影响对它的使用。NRF24L01在单片机和FPGA上的应用的本质是一样的,主要区别就是对上面的A、BSPI方式进行改写。
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 }
跟单片机相比,是不是觉得看得清晰点呢。这就是这个函数的方便之处了。有一点要注意一下,这个函数的最后一个参数的作用,以前没注意,走过一段弯路,它的作用就是相当于上面单片机中的CSN信号,如果需要对SPI从器件进行连续访问,则不释放该信号可以提高访问速度。
好了,差不多就总结到这里了。无线模块的应用很广泛,可以用作无线遥控器、数据的无线烧写等用途。
厉害了,楼主! nRF24L01无线模块在单片机与FPGA上的应用 nRF24L01无线模块在单片机与FPGA上的应用
页:
1
[2]