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

STM32F103C8T6 SPI外设配置异常:MOSI无输出且DR寄存器返回0xFF

SPI1 MOSI无输出且DR寄存器始终返回0xFF的问题排查

问题描述

用示波器监测MOSI引脚无输出,已执行初始化时钟、禁用并重置SPI的CR1寄存器、配置GPIO、设置CR1寄存器后使能SPI的流程。运行测试代码后,调试时SPI->DR寄存器始终返回0xFF。

测试代码

uint8_t buff[3] = {0x66, 0x11, 0x35}
spi1_transmit_blocking(buff, buff_size);

相关spi.c代码

/*
 * spi.c
 *
 *  Created on: May 21, 2026
 *      Author: hillary
 */


#include "spi.h"

void spi1_init(void)
{
    RCC->APB2ENR |= (RCC_APB2ENR_SPI1EN | RCC_APB2ENR_IOPAEN | RCC_APB2ENR_AFIOEN);
    RCC->AHBENR  |= RCC_AHBENR_DMA1EN;
    __DSB();

    // Disable SPI1
    //SPI1->CR1 |= SPI_CR1_SPE;

    // reset cr1 register
    SPI1->CR1 = 0x0000;

    /* Setup SPI1 Pins */
    // PA5 = SPI1 SCK
    // PA7 = SPI_MOSI
    GPIOA->CRL &= ~(GPIO_CRL_MODE5 | GPIO_CRL_CNF5);
    GPIOA->CRL |= (GPIO_CRL_MODE5 | GPIO_CRL_CNF5_1);

    GPIOA->CRL &= ~(GPIO_CRL_CNF7 | GPIO_CRL_MODE7);
    GPIOA->CRL |= (GPIO_CRL_CNF7_1 | GPIO_CRL_MODE7);

    /** Initialise SPI1 CR1 Register **/
    /* Master Mode, Software Slave Management, prescaler /4 */
    SPI1->CR1 |= (SPI_CR1_MSTR | SPI_CR1_SSM | SPI_CR1_SSI | SPI_CR1_BIDIMODE | SPI_CR1_BIDIOE);
    SPI1->CR1 |= SPI_CR1_BR_0;
    SPI1->CR1 |= SPI_CR1_SPE;
}

void spi1_transmit_blocking(const uint8_t *buf, uint16_t len)
{

    if((SPI1->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE){
        SPI1->CR1 |= SPI_CR1_SPE;
    }

    for (uint16_t i = 0; i < len; i++) {
        while (!(SPI1->SR & SPI_SR_TXE));  // wait TX empty
        SPI1->DR = buf[i];
    }

    __IO uint32_t tmpreg_ovr = 0x00U;
    tmpreg_ovr = SPI1->DR;
    tmpreg_ovr = SPI1->SR;
    (void)tmpreg_ovr;
}

排查与解决建议

  • 修复SPI禁用步骤:注释掉的禁用SPI代码逻辑错误,置位SPI_CR1_SPE是启用SPI,正确禁用应清除该位。修改为:

    SPI1->CR1 &= ~SPI_CR1_SPE; // 禁用SPI1
    

    必须在重置CR1前确保SPI处于禁用状态,否则重置操作可能不生效。

  • 检查双向模式配置:当前启用了SPI_CR1_BIDIMODE(双向数据线模式)和SPI_CR1_BIDIOE(输出使能),这种模式下MOSI与MISO共用一根引脚。如果硬件是标准双线SPI(SCK+MOSI),建议关闭双向模式,改用全双工:

    // 移除双向模式相关位,保留主模式、软件从机管理配置
    SPI1->CR1 |= (SPI_CR1_MSTR | SPI_CR1_SSM | SPI_CR1_SSI);
    
  • 完善传输完成等待逻辑:当前仅等待TXE标志,未等待传输完成。在循环结束后添加:

    while (SPI1->SR & SPI_SR_BSY); // 等待所有传输完成
    

    确保数据完全发送后再进行后续操作,避免DR寄存器读取异常。

  • 验证GPIO配置生效:通过调试器读取GPIOA->CRL寄存器值,确认PA5、PA7的配置为复用推挽高速输出(CNFx_1置位、CNFx_0清零,MODEx为0b11)。

  • 确认时钟预分频合理性:SPI_CR1_BR_0对应预分频系数/4,需结合APB2总线时钟确认SPI时钟在硬件允许范围内,若外设不支持当前时钟,需调整预分频位。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.02 04:44:52