You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32 B-L4S5I-IOT01A板BlueNRG-MS SPI通信无响应求助

STM32L4S5与BlueNRG-MS SPI通信收全0问题排查与解决

我使用B-L4S5I-IOT01A开发板(主控为STM32L4S5VIT6),该板通过SPI3连接BlueNRG-MS模块。我通过以下函数配置BLE相关的SPI:

HAL_StatusTypeDef ble_init()
{
    __HAL_RCC_GPIOC_CLK_ENABLE();
    GPIO_InitTypeDef gpio;
    gpio.Pin = GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12; // PC10 - SPI3_CLK, PC11 - SPI3_MISO, PC12 - SPI3_MOSI
    gpio.Mode = GPIO_MODE_AF_PP;
    gpio.Alternate = GPIO_AF6_SPI3;
    HAL_GPIO_Init(GPIOC, &gpio);

    __HAL_RCC_GPIOD_CLK_ENABLE();
    GPIO_InitTypeDef gpio_cs;
    gpio.Pin = GPIO_PIN_13; // PD13 - SPBTLE-RF-SPI3_CSN
    gpio.Mode = GPIO_MODE_OUTPUT_PP;
    HAL_GPIO_Init(GPIOD, &gpio_cs);

    __HAL_RCC_SPI3_CLK_ENABLE();
    spi.Instance = SPI3;
    spi.Init.Mode = SPI_MODE_MASTER;
    spi.Init.Direction = SPI_DIRECTION_2LINES;
    spi.Init.NSS = SPI_NSS_SOFT;
    spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
    HAL_StatusTypeDef status = HAL_SPI_Init(&spi);
    __HAL_SPI_ENABLE(&spi);
    return status;
}

HAL_StatusTypeDef spi_send_recv(uint8_t *send_buf, uint8_t *recv_buf, size_t size)
{
    HAL_StatusTypeDef status = HAL_SPI_TransmitReceive(&spi, send_buf, recv_buf, size, HAL_MAX_DELAY);
    return status;
}

我理解SPI通信流程应为:拉低CS引脚,收发数据,再拉高CS引脚。根据BlueNRG-MS蓝牙手册,第一个接收字节应返回正确状态值0x02,但目前我接收的所有字节均为0。请问还需要执行哪些额外步骤才能正常使用该SPI通信?

主函数代码如下:

int main() 
{
    SystemCoreClock = 4000000;
    HAL_Init();

    ble_init();

    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, GPIO_PIN_SET);

    while (1) {
      HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, GPIO_PIN_RESET);
      uint8_t tx[5] = {0x0a,0,0,0,0};
      uint8_t rx[5];
      spi_send_recv(tx, rx, 5);
      HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, GPIO_PIN_SET);
    }
}

排查与解决步骤

  • 补全SPI关键初始化参数:当前SPI配置缺少时钟极性、相位等核心参数,必须与BlueNRG-MS的默认配置匹配:

    spi.Init.CLKPolarity = SPI_POLARITY_LOW;       // 模块默认时钟空闲为低电平
    spi.Init.CLKPhase = SPI_PHASE_1EDGE;           // 第一个时钟沿采样数据
    spi.Init.DataSize = SPI_DATASIZE_8BIT;         // 明确8位数据传输
    spi.Init.FirstBit = SPI_FIRSTBIT_MSB;          // 蓝牙模块通常采用MSB先发
    
  • 修正CS引脚初始化错误:代码中定义了gpio_cs结构体,但初始化时错误传入了&gpio,导致PD13配置失效,修正后需加上上拉和速度配置:

    GPIO_InitTypeDef gpio_cs;
    gpio_cs.Pin = GPIO_PIN_13; 
    gpio_cs.Mode = GPIO_MODE_OUTPUT_PP;
    gpio_cs.Pull = GPIO_PULLUP;    // 上拉避免引脚浮空
    gpio_cs.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOD, &gpio_cs);
    
  • 执行BlueNRG-MS复位流程:模块上电后需要复位才能进入工作状态,需按硬件设计操作复位引脚(查B-L4S5I-IOT01A原理图确认复位引脚,比如PD12):

    // 示例:假设复位引脚为PD12
    __HAL_RCC_GPIOD_CLK_ENABLE();
    GPIO_InitTypeDef gpio_rst;
    gpio_rst.Pin = GPIO_PIN_12;
    gpio_rst.Mode = GPIO_MODE_OUTPUT_PP;
    HAL_GPIO_Init(GPIOD, &gpio_rst);
    
    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_RESET);
    HAL_Delay(10);  // 拉低复位至少10ms
    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_SET);
    HAL_Delay(50);  // 等待模块初始化完成
    
  • 修正系统时钟配置:不要直接硬写SystemCoreClock,应调用SystemCoreClockUpdate()获取实际时钟值,确保SPI时钟计算准确:

    int main() 
    {
        HAL_Init();
        SystemCoreClockUpdate();  // 替换硬写的SystemCoreClock赋值
        ble_init();
        // ... 后续代码
    }
    
  • 增加时序延迟:拉低CS后需给模块足够的检测时间,收发完成后确保数据传输完毕再拉高CS:

    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, GPIO_PIN_RESET);
    HAL_Delay(1);  // 短延迟确保模块识别CS拉低
    spi_send_recv(tx, rx, 5);
    HAL_Delay(1);  // 等待最后一个字节传输完成
    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, GPIO_PIN_SET);
    
  • 验证命令格式合法性:确认发送的0x0A命令符合BlueNRG-MS的帧格式要求,部分命令需要前缀、长度字段或校验位,需严格遵循手册定义的通信协议。


内容的提问来源于stack exchange,提问作者Witnes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 03:53:19