NRF24L01--使用STM32F103

Posted WHLOOK

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NRF24L01--使用STM32F103相关的知识,希望对你有一定的参考价值。

看了两天的24l01的相关资料了,一直有点模糊,今天下午感觉有点懂了,在板子上调试成功了,但是还没进行通讯测试。stm32和arduino进行通信还没成功 ,:(

先把stm32的NRF24L01配置的过程说一下吧(这是我跟着代码写的,有点简单,可能还有差错):

1 . 首先初始化相关的端口和SPI等

 void SPI2_NRF24L01_init(void)   
  {
    SPI_InitTypeDef  SPI_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;
 
    /* Enable SPI2 GPIOB clocks */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2 ,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC, ENABLE);
    /* Configure SPI2 pins: SCK, MISO and MOSI */
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//GPIO_Mode_Out_PP; //
   GPIO_Init(GPIOB, &GPIO_InitStructure);
     
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_Init(GPIOC,&GPIO_InitStructure);
     
 
   /* Configure PB.11 as Output push-pull, used as Flash Chip select */
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
   GPIO_Init(GPIOB, &GPIO_InitStructure);

  
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;                //NRF24L01  MODE-CE
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
   GPIO_Init(GPIOC, &GPIO_InitStructure);
   /* Deselect the FLASH: Chip Select high */
 
 
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;         //NRF24L01 IRQ 
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
   GPIO_Init(GPIOB, &GPIO_InitStructure);
   GPIO_SetBits(GPIOB, GPIO_Pin_8);        //On
   NotSelect_SDR();
 
   /* SPI2 configuration */ 
     SPI_Cmd(SPI2,DISABLE);
   SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
   SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
   SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
   SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
   SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
   SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
   SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
   SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
   SPI_InitStructure.SPI_CRCPolynomial = 7;
   SPI_Init(SPI2,&SPI_InitStructure);
   
   /* Enable SPI2  */
     SPI_Cmd(SPI2,ENABLE);  
 }

 

  

 

这是我的引脚连接。

2 . 然后开始初始化 NRF模块

      01 . spi的读、写数据方法:

 1 u8 Spi_RW(u8 dat) 
 2 { 
 3     /* 当 SPI发送缓冲器非空时等待 */ 
 4     while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET); 
 5     /* 通过 SPI2发送一字节数据 */ 
 6     SPI_I2S_SendData(SPI2, dat); 
 7     /* 当SPI接收缓冲器为空时等待 */ 
 8     while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
 9     /* Return the byte read from the SPI bus */ 
10     return SPI_I2S_ReceiveData(SPI2); 
11 }

 

        模块的读、写方法:

 1 uint8_t NRF_Read_Reg(uint8_t reg)    
 2 {
 3 uint8_t reg_val;
 4 SPI_CSN_L();            /* 选通器件 */
 5 Spi_RW(reg);            /* 写寄存器地址 */
 6 reg_val = Spi_RW(0);    /* 读取该寄存器返回数据   #define NRF_READ_REG        0x00   // 读寄存器指令   */
 7 SPI_CSN_H();            /* 禁止该器件 */
 8 return reg_val;
 9 }
10 
11 uint8_t NRF_Write_Reg(uint8_t reg, uint8_t value)
12 {
13     uint8_t status;
14     SPI_CSN_L();          /* 先选通器件 */
15     status = Spi_RW(reg); /* 写寄存器地址,同时也可以读出该寄存器 */
16     Spi_RW(value);        /* 然后就向该地址的寄存器写数据 */
17     SPI_CSN_H();          /* 最后禁止该器件 */
18   return     status;
19 }

    02 . 然后就是按照模块的寄存器说明来向相应的寄存器里写入数据来设置:

1 NRF_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,RX_ADDRESS,RX_ADR_WIDTH);    //写RX节点地址 
2 NRF_Write_Buf(NRF_WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH);   //写TX节点地址  
3 NRF_Write_Reg(NRF_WRITE_REG+EN_AA,0x01);           //使能通道0的自动应答 
4 NRF_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01);       //使能通道0的接收地址 
5 NRF_Write_Reg(NRF_WRITE_REG+SETUP_RETR,0x1a);      //设置自动重发间隔时间:500us;最大自动重发次数:10次 
6 NRF_Write_Reg(NRF_WRITE_REG+RF_CH,40);             //设置RF通道为CHANAL
7 NRF_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f);        //设置TX发射参数,0db增益,2Mbps,低噪声增益开启

            这些寄存器的地址和设置的数据在NRF24L01.h中都有宏定义:

 1 //***************************************NRF24L01寄存器指令*******************************************************
 2 #define NRF_READ_REG        0x00      // 读寄存器指令
 3 #define NRF_WRITE_REG       0x20     // 写寄存器指令
 4 #define R_RX_PL_WID       0x60
 5 #define RD_RX_PLOAD     0x61      // 读取接收数据指令
 6 #define WR_TX_PLOAD     0xA0      // 写待发数据指令
 7 #define FLUSH_TX        0xE1     // 冲洗发送 FIFO指令
 8 #define FLUSH_RX        0xE2      // 冲洗接收 FIFO指令
 9 #define REUSE_TX_PL     0xE3      // 定义重复装载数据指令
10 #define NOP             0xFF      // 保留
11 //*************************************SPI(nRF24L01)寄存器地址****************************************************
12 #define CONFIG          0x00  // 配置收发状态,CRC校验模式以及收发状态响应方式
13 #define EN_AA           0x01  // 自动应答功能设置
14 #define EN_RXADDR       0x02  // 可用信道设置
15 #define SETUP_AW        0x03  // 收发地址宽度设置
16 #define SETUP_RETR      0x04  // 自动重发功能设置
17 #define RF_CH           0x05  // 工作频率设置
18 #define RF_SETUP        0x06  // 发射速率、功耗功能设置
19 #define NRFRegSTATUS    0x07  // 状态寄存器
20 #define OBSERVE_TX      0x08  // 发送监测功能
21 #define CD              0x09  // 地址检测           
22 #define RX_ADDR_P0      0x0A  // 频道0接收数据地址
23 #define RX_ADDR_P1      0x0B  // 频道1接收数据地址
24 #define RX_ADDR_P2      0x0C  // 频道2接收数据地址
25 #define RX_ADDR_P3      0x0D  // 频道3接收数据地址
26 #define RX_ADDR_P4      0x0E  // 频道4接收数据地址
27 #define RX_ADDR_P5      0x0F  // 频道5接收数据地址
28 #define TX_ADDR         0x10  // 发送地址寄存器
29 #define RX_PW_P0        0x11  // 接收频道0接收数据长度
30 #define RX_PW_P1        0x12  // 接收频道1接收数据长度
31 #define RX_PW_P2        0x13  // 接收频道2接收数据长度
32 #define RX_PW_P3        0x14  // 接收频道3接收数据长度
33 #define RX_PW_P4        0x15  // 接收频道4接收数据长度
34 #define RX_PW_P5        0x16  // 接收频道5接收数据长度
35 #define FIFO_STATUS     0x17  // FIFO栈入栈出状态寄存器设置
36 //**************************************************************************************
37 //*********************************************NRF24L01*************************************
38 #define RX_DR                6        //中断标志
39 #define TX_DS                5
40 #define MAX_RT            4
41 
42 #define MODEL_RX                1            //普通接收
43 #define MODEL_TX                2            //普通发送
44 #define MODEL_RX2                3            //接收模式2,用于双向传输
45 #define MODEL_TX2                4            //发送模式2,用于双向传输
46 
47 #define RX_PLOAD_WIDTH  32      
48 #define TX_PLOAD_WIDTH  32      
49 #define TX_ADR_WIDTH    5          
50 #define RX_ADR_WIDTH    5       

    03 . 基本都设置好了,还要设置一下发送模式

1 NRF_Write_Reg(NRF_WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断开启,16位CRC,主发送
2 NRF_Write_Reg(FLUSH_TX,0xff);
3 NRF_Write_Reg(FLUSH_RX,0xff);
4          
5 Spi_RW(0x50);
6 Spi_RW(0x73);
7 NRF_Write_Reg(NRF_WRITE_REG+0x1c,0x01);
8 NRF_Write_Reg(NRF_WRITE_REG+0x1d,0x07);

    04 . 最后check一下模块和STM32是否连接成功:

 1 u8 Nrf24l01_Check(void)
 2 { 
 3     u8 buf1[5]; 
 4     u8 i; 
 5     /*写入5个字节的地址. */ 
 6     NRF_Write_Buf(NRF_WRITE_REG+TX_ADDR,TX_ADDRESS,5); 
 7     /*读出写入的地址 */ 
 8     NRF_Read_Buf(TX_ADDR,buf1,5); 
 9     /*比较*/ 
10     for(i=0;i<5;i++) 
11     { 
12         if(buf1[i]!=TX_ADDRESS[i]) 
13             break; 
14     } 
15     if(i==5)
16         return SUCCESS ; //MCU与NRF成功连接 
17     else
18         return ERROR ; //MCU与NRF不正常连接 
19 }

 

3 . NRF24L01 发送数据方式 :

    先拉低CE ,然后 将数据写入 TX_FIFO ,然后拉高CE,保持10us以上,数据会无线发送出去。

 

以上是关于NRF24L01--使用STM32F103的主要内容,如果未能解决你的问题,请参考以下文章

NRF24L01连接STM32F103C8实现2.4GHZ无线传输

使用STM32F030F4P6的SPI协议和NRF24L01模块进行通讯 实现无线数据的收发

STM32STM32F103C8T6+nrf24l01收发示例

015_STM32程序移植之_NRF24L01模块

GD32F103学习笔记——在GD32F103移植STM32F103代码

[STM32F103]PWM输入捕获配置