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

Winbond W25Q与STM32F411 Blackpill SPI通信无响应问题

STM32F411 Blackpill W25Q SPI通信无MISO响应排查方案

核心故障原因

PB4引脚默认复用为JTAG调试接口的NJTRST功能,现有代码未释放该引脚的JTAG占用,导致PB4无法切换为SPI1_MISO复用功能,闪存返回的MISO信号完全无法被MCU采集。

修复步骤

  • 释放JTAG占用的PB4引脚
    在GPIO初始化流程最开头增加SYSCFG时钟使能、JTAG禁用配置,保留SWD调试功能(不影响ST-Link正常下载调试),即可释放PA15、PB3、PB4三个被JTAG占用的引脚。
  • 匹配SPI数据位宽
    当前SPI配置为8位帧格式(DFF=0),但收发函数使用uint16_t类型访问数据寄存器,存在触发帧错位的风险,建议统一改为8位类型,强制按字节访问数据寄存器。
  • 补全SPI引脚速率配置
    现有代码仅配置了CS引脚(PA4)的输出速率,SCK、MOSI、MISO引脚默认工作在低速模式,建议统一配置为最高速率,适配后续更高SPI时钟的运行需求。
  • 清空SPI初始化残留数据
    SPI外设使能后,数据寄存器可能残留上电随机值,建议初始化完成后主动读一次数据寄存器清空缓冲区,避免首次接收数据出错。

修正后的关键代码

uint32_t w25_pin_spi_init(void)
{
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN;
    // 新增:开SYSCFG时钟,释放JTAG占用引脚
    RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
    SYSCFG->CFGR &= ~SYSCFG_CFGR_SWJ_CFG;
    SYSCFG->CFGR |= SYSCFG_CFGR_SWJ_CFG_1; // 关闭JTAG,保留SWD

    /* 配置PA4(CS)为输出、PA5/PA7/PB4为复用功能 */
    GPIOA->MODER &= ~(GPIO_MODER_MODE4 | GPIO_MODER_MODE5 | GPIO_MODER_MODE7);
    GPIOB->MODER &= ~GPIO_MODER_MODE4;

    GPIOA->MODER |= GPIO_MODER_MODE4_0;
    GPIOA->MODER |= (GPIO_MODER_MODE5_1 | GPIO_MODER_MODE7_1);
    GPIOB->MODER |= GPIO_MODER_MODE4_1;

    // 新增:配置所有SPI相关引脚为最高速率
    GPIOA->OSPEEDR |= (GPIO_OSPEEDR_OSPEED4 | GPIO_OSPEEDR_OSPEED5 | GPIO_OSPEEDR_OSPEED7);
    GPIOB->OSPEEDR |= GPIO_OSPEEDR_OSPEED4;

    /* 推挽模式为复位默认值,无需额外配置 */
    GPIOA->PUPDR &= ~(GPIO_PUPDR_PUPD4 | GPIO_PUPDR_PUPD5 | GPIO_PUPDR_PUPD7);
    GPIOB->PUPDR &= ~GPIO_PUPDR_PUPD4;
    /* MISO配置上拉 */
    GPIOB->PUPDR |= GPIO_PUPDR_PUPD4_0;

    // AF5对应SPI1功能,原配置正确
    GPIOA->AFR[0] |= (GPIO_AFRL_AFSEL5_0 | GPIO_AFRL_AFSEL5_2);
    GPIOA->AFR[0] |= (GPIO_AFRL_AFSEL7_0 | GPIO_AFRL_AFSEL7_2);
    GPIOB->AFR[0] |= (GPIO_AFRL_AFSEL4_0 | GPIO_AFRL_AFSEL4_2);

    return 0;
}

void w25_CS_enable(void)
{
    GPIOA->BSRR = GPIO_BSRR_BR4; // BSRR写1有效,直接赋值即可无需|=
}

void w25_CS_disable (void)
{
    GPIOA->BSRR = GPIO_BSRR_BS4;
}

uint32_t w25_spi_init(void)
{
    RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
    SPI1->CR1 = 0; // 先清空寄存器原有配置
    SPI1->CR1 &= ~SPI_CR1_DFF; // 8位帧格式
    SPI1->CR1 |= (SPI_CR1_BR_2 | SPI_CR1_BR_1 | SPI_CR1_BR_0); // 256分频,约390kHz
    SPI1->CR1 |= SPI_CR1_MSTR; // 主机模式
    SPI1->CR1 |= SPI_CR1_SSM; // 软件控制CS
    SPI1->CR1 |= SPI_CR1_SSI; // 内部NSS拉高,避免误进入从模式
    SPI1->CR1 |= SPI_CR1_SPE; // 使能SPI外设

    // 新增:清空接收缓冲区残留数据
    volatile uint8_t dummy = *(volatile uint8_t*)&SPI1->DR;
    (void)dummy;

    return 0;
}

// 修正为8位数据类型,强制按字节访问DR寄存器
uint8_t w25_send_receive_data(uint8_t data)
{
    while(!(SPI1->SR & SPI_SR_TXE));
    *(volatile uint8_t*)&SPI1->DR = data;
    while(!(SPI1->SR & SPI_SR_RXNE));
    return *(volatile uint8_t*)&SPI1->DR;
}

验证方法

  • 引脚释放验证:可临时将PB4配置为推挽输出,反复写高/写低,用万用表或示波器测量引脚电平是否随配置变化,确认引脚已脱离JTAG控制。
  • 功能验证:运行读JEDEC ID代码,正常返回值为:制造商ID0xEF、存储类型0x40、容量码0x17(对应W25Q64)。
  • 硬件排查:若仍无响应,测量W25Q的VCC引脚电压为3.3V、GND引脚可靠接地,排除芯片焊接虚焊问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 02:45:30