STM32
直播中

刘伟

7年用户 1637经验值
私信 关注
[问答]

如何对stm32的NRF24L01模块进行配置呢

如何对STM32的NRF24L01模块进行配置呢?其过程是怎样的?

回帖(1)

许海明

2021-12-16 11:29:45
酷酷的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的读、写数据方法:
  
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 . 最后检查一下模块和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!=TX_ADDRESS)
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以上,数据会无线发送出去。
举报

更多回帖

×
20
完善资料,
赚取积分