乐鑫技术交流
直播中

张虎豹

8年用户 1666经验值
私信 关注
[问答]

如何使用RTOS SDK才能正确驱动NRF24L模块呢?

你好,我刚接触 ESP8266 TROS SDK,想用ESP8266的HSPI驱动NRF24L01模块,自己模拟SPI时序可以正常驱动NRF24L01,但通信速率只有350K左右。请问如何使用RTOS SDK才能正确驱动NRF24L模块呢?关键在于要如何用RTOS SDK里面的函数来替换我的SPI2_ReadWriteByte函数(全双工)。
RTOS SDK HSPI 代码

void MySPI_Init(void)
{
    SpiAttr hSpiAttr;
    hSpiAttr.bitOrder = SpiBitOrder_MSBFirst;
    hSpiAttr.speed = SpiSpeed_2MHz;
    hSpiAttr.mode = SpiMode_Master;Code: Select all


    hSpiAttr.subMode = SpiSubMode_0;

    // Init HSPI GPIO
    WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105);
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 2);//configure io to spi mode
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 2);//configure io to spi mode
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2);//configure io to spi mode
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, 2);//configure io to spi mode

    SPIInit(SpiNum_HSPI, &hSpiAttr);
}

我发现RTOS SPI 里面主要由spi_transaction函数处理接收和发送。
还有以下宏和定义
uint32 spi_transaction(uint8 spi_no, uint8 cmd_bits, uint16 cmd_data, uint32 addr_bits, uint32 addr_data, uint32 dout_bits, uint32 dout_data, uint32 din_bits, uint32 dummy_bits);

#define spi_busy(spi_no) READ_PERI_REG(SPI_CMD(spi_no))&SPI_USR

#define spi_txd(spi_no, bits, data) spi_transaction(spi_no, 0, 0, 0, 0, bits, (uint32) data, 0, 0)
#define spi_tx8(spi_no, data)       spi_transaction(spi_no, 0, 0, 0, 0, 8,    (uint32) data, 0, 0)
#define spi_tx16(spi_no, data)      spi_transaction(spi_no, 0, 0, 0, 0, 16,   (uint32) data, 0, 0)
#define spi_tx32(spi_no, data)      spi_transaction(spi_no, 0, 0, 0, 0, 32,   (uint32) data, 0, 0)

#define spi_rxd(spi_no, bits) spi_transaction(spi_no, 0, 0, 0, 0, 0, 0, bits, 0)
#define spi_rx8(spi_no)       spi_transaction(spi_no, 0, 0, 0, 0, 0, 0, 8,    0)
#define spi_rx16(spi_no)      spi_transaction(spi_no, 0, 0, 0, 0, 0, 0, 16,   0)
#define spi_rx32(spi_no)      spi_transaction(spi_no, 0, 0, 0, 0, 0, 0, 32,   0)


我的模拟SPI代码
const u8 TX_ADDRESS[TX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; //发送地址
const u8 RX_ADDRESS[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; //发送地址
//MISO->GPIO12
//MOSI->GPIO13
//SCK->GPIO14
//CSN->GPIO15

//IRQ->GPIO2
//CE->GPIO5
u8 NRF24L01_MISO()//输入
{
        u8 result;
        result = GPIO_INPUT_GET(GPIO_ID_PIN(12));
        return result;
}

void NRF24L01_MOSI(u8 level)
{
        GPIO_OUTPUT_SET(GPIO_ID_PIN(13), level);
}

void NRF24L01_SCK(u8 level)
{
        GPIO_OUTPUT_SET(GPIO_ID_PIN(14), level);
}


void NRF24L01_CSN(u8 level)
{
        GPIO_OUTPUT_SET(GPIO_ID_PIN(15), level);
}

void NRF24L01_CE(u8 level)
{
        GPIO_OUTPUT_SET(GPIO_ID_PIN(5), level);
}

u8 NRF24L01_IRQ() //输入
{
        u8 result;
        result = GPIO_INPUT_GET(GPIO_ID_PIN(2));
        return result;
}

void NRF24L01_Init(void)
{
        PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO12);  //输入

        PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_GPIO13);
        PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, FUNC_GPIO14);
        PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_GPIO15);
        
        PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO5_U, FUNC_GPIO5);
        PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2);  //输入

        NRF24L01_CE(0);
        NRF24L01_CSN(1);
}

uint8 SPI2_ReadWriteByte(uint8 u8_writedata)
{
  uint8 i;
  uint8 u8_readdata = 0x00;
     
  for(i=0;i<8;i++)
  {
    u8_readdata <<= 1;      //读取MISO 8次输入的值,存入u8_readdata。
      
    if(u8_writedata & 0x80) //判断最高位,总是写最高位(输出最高位)
        {
      NRF24L01_MOSI(1);              //MOSI输出1,数据总线准备数据1
        }
    else
        {
      NRF24L01_MOSI(0);             //MOSI输出0,数据总线准备数据0
        }
    u8_writedata <<= 1;     //左移抛弃已经输出的最高位
      
    NRF24L01_SCK(1);               //上升沿来了(SCK从0-->1),数据总线上的数据写入器件
    if(NRF24L01_MISO())                //读取最高位,保存至最末尾,通过左移位完成读整个字节
        {
      u8_readdata |= 0x01;
        }
    else
        {
      u8_readdata &= ~0x01;
        }
        
    NRF24L01_SCK(0);               //下降沿来了(SCK从1-->0),MISO上将产生新的数据,读取存入u8——readdata
   }
  return u8_readdata;
}

u8 NRF24L01_Write_Reg(u8 reg,u8 value)
{
        u8 status;        
           NRF24L01_CSN(0);                  
          status =SPI2_ReadWriteByte(reg);
          SPI2_ReadWriteByte(value);      
          NRF24L01_CSN(1);                 
          return(status);                              
}
u8 NRF24L01_Read_Reg(u8 reg)
{
        u8 reg_val;            
         NRF24L01_CSN(0);         
          SPI2_ReadWriteByte(reg);   
          reg_val=SPI2_ReadWriteByte(0XFF);
          NRF24L01_CSN(1);         
          return(reg_val);           
}        


u8 NRF24L01_Read_Buf(u8 reg,u8 *pBuf,u8 len)
{
        u8 status,u8_ctr;               
          NRF24L01_CSN(0);           
          status=SPI2_ReadWriteByte(reg);
         for(u8_ctr=0;u8_ctrGPIO12
//MOSI->GPIO13
//SCK->GPIO14
//CSN->GPIO15

//IRQ->GPIO2
//CE->GPIO5
u8 NRF24L01_MISO()//输入
{
        u8 result;
        result = GPIO_INPUT_GET(GPIO_ID_PIN(12));
        return result;
}

void NRF24L01_MOSI(u8 level)
{
        GPIO_OUTPUT_SET(GPIO_ID_PIN(13), level);
}

void NRF24L01_SCK(u8 level)
{
        GPIO_OUTPUT_SET(GPIO_ID_PIN(14), level);
}


void NRF24L01_CSN(u8 level)
{
        GPIO_OUTPUT_SET(GPIO_ID_PIN(15), level);
}

void NRF24L01_CE(u8 level)
{
        GPIO_OUTPUT_SET(GPIO_ID_PIN(5), level);
}

u8 NRF24L01_IRQ() //输入
{
        u8 result;
        result = GPIO_INPUT_GET(GPIO_ID_PIN(2));
        return result;
}

void NRF24L01_Init(void)
{
        PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO12);  //输入

        PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_GPIO13);
        PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, FUNC_GPIO14);
        PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_GPIO15);
        
        PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO5_U, FUNC_GPIO5);
        PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2);  //输入

        NRF24L01_CE(0);
        NRF24L01_CSN(1);
}

uint8 SPI2_ReadWriteByte(uint8 u8_writedata)
{
  uint8 i;
  uint8 u8_readdata = 0x00;
     
  for(i=0;i<8;i++)
  {
    u8_readdata <<= 1;      //读取MISO 8次输入的值,存入u8_readdata。
      
    if(u8_writedata & 0x80) //判断最高位,总是写最高位(输出最高位)
        {
      NRF24L01_MOSI(1);              //MOSI输出1,数据总线准备数据1
        }
    else
        {
      NRF24L01_MOSI(0);             //MOSI输出0,数据总线准备数据0
        }
    u8_writedata <<= 1;     //左移抛弃已经输出的最高位
      
    NRF24L01_SCK(1);               //上升沿来了(SCK从0-->1),数据总线上的数据写入器件
    if(NRF24L01_MISO())                //读取最高位,保存至最末尾,通过左移位完成读整个字节
        {
      u8_readdata |= 0x01;
        }
    else
        {
      u8_readdata &= ~0x01;
        }
        
    NRF24L01_SCK(0);               //下降沿来了(SCK从1-->0),MISO上将产生新的数据,读取存入u8——readdata
   }
  return u8_readdata;
}

u8 NRF24L01_Write_Reg(u8 reg,u8 value)
{
        u8 status;        
           NRF24L01_CSN(0);                  
          status =SPI2_ReadWriteByte(reg);
          SPI2_ReadWriteByte(value);      
          NRF24L01_CSN(1);                 
          return(status);                              
}
u8 NRF24L01_Read_Reg(u8 reg)
{
        u8 reg_val;            
         NRF24L01_CSN(0);         
          SPI2_ReadWriteByte(reg);   
          reg_val=SPI2_ReadWriteByte(0XFF);
          NRF24L01_CSN(1);         
          return(reg_val);           
}        


u8 NRF24L01_Read_Buf(u8 reg,u8 *pBuf,u8 len)
{
        u8 status,u8_ctr;               
          NRF24L01_CSN(0);           
          status=SPI2_ReadWriteByte(reg);
         for(u8_ctr=0;u8_ctr

回帖(1)

人走了

2024-7-20 16:34:29
要使用RTOS SDK正确驱动NRF24L01模块,你需要遵循以下步骤:

1. 初始化SPI接口:
首先,你需要初始化SPI接口,使用RTOS SDK提供的Spi_Init函数。在这个函数中,你可以设置SPI的工作模式、速率和时序。以下是初始化SPI接口的示例代码:

```c
void MySPI_Init(void) {
    SpiAttr hSpiAttr;
    hSpiAttr.bitOrder = SpiBitOrder_MSBFirst;
    hSpiAttr.speed = SpiSpeed_2MHz;
    hSpiAttr.mode = SpiMode_Master;
    hSpiAttr.csPolarity = SpiCsPolarity_ActiveLow;

    Spi_Init(SPI2, &hSpiAttr);
}
```

2. 编写SPI读写函数:
接下来,你需要编写一个SPI读写函数,用于替换你的SPI2_ReadWriteByte函数。这个函数将使用RTOS SDK提供的Spi_WriteRead函数来实现全双工通信。以下是SPI读写函数的示例代码:

```c
uint8_t MySPI_WriteReadByte(uint8_t data) {
    uint8_t receivedData;
    Spi_WriteRead(SPI2, &data, &receivedData, 1);
    return receivedData;
}
```

3. 使用SPI读写函数与NRF24L01模块通信:
现在,你可以使用MySPI_WriteReadByte函数来与NRF24L01模块进行通信。以下是与NRF24L01模块通信的示例代码:

```c
void NRF24L01_WriteRegister(uint8_t reg, uint8_t value) {
    MySPI_WriteReadByte((reg & 0xE0) | 0x20); // 发送写入寄存器命令
    MySPI_WriteReadByte(value); // 发送数据
}

uint8_t NRF24L01_ReadRegister(uint8_t reg) {
    MySPI_WriteReadByte(reg); // 发送读取寄存器命令
    return MySPI_WriteReadByte(0); // 读取数据
}
```

4. 配置NRF24L01模块:
在与NRF24L01模块通信之前,你需要配置模块的寄存器。以下是配置NRF24L01模块的示例代码:

```c
void NRF24L01_Init(void) {
    MySPI_Init(); // 初始化SPI接口

    // 配置NRF24L01模块
    NRF24L01_WriteRegister(NRF24L01_0x00_CONFIG, 0x0F); // 配置配置寄存器
    NRF24L01_WriteRegister(NRF24L01_0x01_EN_AA, 0x3F); // 配置自动应答寄存器
    // ... 配置其他寄存器
}
```

5. 测试通信速率:
使用RTOS SDK提供的SPI接口,你应该能够达到更高的通信速率。如果仍然遇到通信速率较低的问题,可以尝试调整SPI速率或检查硬件连接。

通过以上步骤,你应该能够使用RTOS SDK正确驱动NRF24L01模块。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分