STM32H750 SPI1从机模式回复异常问题排查求助
STM32H750 SPI从机回复异常排查方案
问题概述
STM32H750作为SPI从机时,可正常接收主机数据,但调用HAL_SPI_TransmitReceive()回复时,主机收到全0x02数据,函数返回HAL_TIMEOUT;调试发现__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP)始终为0,数据未写入发送寄存器。设备作为主机时收发功能正常。
核心现象分析
- 接收正常说明SPI时钟、NSS、MOSI/MISO硬件连接基本正常,从机RX路径工作逻辑无问题;
- TXP标志持续为0,说明发送寄存器未进入可写入状态,或从机发送逻辑未被正确触发;
- 主机收到的0x02大概率是从机发送寄存器的复位残留值或未及时填充数据时的默认输出。
具体排查与解决步骤
1. 替换同步收发函数为中断/DMA模式
SPI从机的发送完全由主机时钟驱动,HAL_SPI_TransmitReceive()的同步等待逻辑存在时序缺陷:主机发起传输时,从机尚未填充发送数据,导致先发默认值,后续因时钟同步问题无法捕获TXP标志,最终超时。
中断模式示例代码:
// 全局缓冲区与索引 uint8_t tx_buf[100]; uint8_t rx_buf[100]; uint16_t tx_idx = 0; uint16_t rx_idx = 0; // 初始化时预加载第一个发送数据并开启接收中断 void SPI_Slave_Init_Ext(void) { // 填充发送缓冲区 for (size_t i = 0; i < 100; i++) { tx_buf[i] = i + 1; } // 预加载第一个发送数据 *(__IO uint8_t *)&hspi1.Instance->TXDR = tx_buf[tx_idx++]; // 开启接收中断 HAL_SPI_Receive_IT(&hspi1, &rx_buf[rx_idx], 1); } // TXE中断回调:继续填充发送数据 void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) { if (hspi->Instance == SPI1 && tx_idx < 100) { *(__IO uint8_t *)&hspi1.Instance->TXDR = tx_buf[tx_idx++]; HAL_SPI_Transmit_IT(&hspi1, &tx_buf[tx_idx], 1); } } // RXNE中断回调:继续接收数据 void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) { if (hspi->Instance == SPI1 && rx_idx < 99) { rx_idx++; HAL_SPI_Receive_IT(&hspi1, &rx_buf[rx_idx], 1); } }
2. 调整SPI FIFO阈值配置
当前初始化中SPI_FIFO_THRESHOLD_01DATA的配置,在从机模式下可能导致TXP标志触发时机与主机时钟不匹配。尝试修改为SPI_FIFO_THRESHOLD_04DATA,或调整CR2寄存器的FTHLV位:
// 初始化后修改FIFO阈值 hspi1.Instance->CR2 &= ~SPI_CR2_FTHLV; hspi1.Instance->CR2 |= SPI_CR2_FTHLV_0; // 配置为4数据阈值
3. 验证NSS信号配置与硬件连接
- 确认主机NSS输出极性与从机
SPI_NSS_POLARITY_LOW配置一致; - 检查NSS引脚硬件连接,确保无虚焊、信号毛刺,必要时添加上拉电阻;
- 尝试将
SPI_NSSPMode改为SPI_NSS_PULSE_ENABLE,适配主机的NSS脉冲模式。
4. 检查SPI外设时钟配置
确认APB2总线时钟(SPI1挂载总线)配置正确,频率需满足从机数据处理需求,避免因时钟不足导致发送寄存器写入延迟。
5. 硬件信号完整性验证
用逻辑分析仪抓取MISO引脚信号,检查是否存在电平异常、信号衰减:
- 若信号毛刺多,优化PCB布线(缩短线长、增加接地);
- 若MISO驱动能力不足,添加外部上拉电阻增强信号强度。
内容的提问来源于stack exchange,提问作者余家航
相关产品推荐
相关产品推荐

