问题描述在使用 STM32H7 系列微控制器驱动 AD9959 DDS 芯片时发现硬件 SPI 的 SCK 引脚存在异常行为无论 CPOLClock Polarity时钟极性配置为 0 还是 1SCK 引脚在传输完成后的空闲状态始终为高电平。这导致无法与 AD9959 正常通信AD9959 仅支持 SPI 模式 0即 CPOL0, CPHA0。波形对比分析期望波形理想的 SPI 模式 0 时序应满足SCK 空闲状态为低电平CPOL0数据在 SCK 上升沿采样CPHA0图 1理想 SPI 时序概览图 2理想 SPI 时序细节图 3理想波形局部放大实际波形使用 CubeMX 配置的硬件 SPICPOL0, CPHA1产生的实际波形如下图 4实际 SPI 时序概览图 5实际 SPI 时序细节图 6实际波形局部放大CubeMX 配置SPI 基础参数配置如下Mode: Transmit Only MasterCPOL: Low时钟空闲时为低电平CPHA: 1 Edge第二个边沿采样图 7CubeMX SPI 基础配置代码实现// AD9959.cvoidAD9959_WriteData(uint8_tRegisterAddress,uint8_tNumberofRegisters,uint8_t*RegisterData){// 发送寄存器地址HAL_GPIO_WritePin(AD9959_CS_GPIO_Port,AD9959_CS_Pin,GPIO_PIN_RESET);HAL_SPI_Transmit_IT(hspi_ad9959,RegisterAddress,1);while(!g_ad9959_spi_tx_cplt){__NOP();}g_ad9959_spi_tx_cpltfalse;// 发送寄存器数据HAL_GPIO_WritePin(AD9959_CS_GPIO_Port,AD9959_CS_Pin,GPIO_PIN_RESET);HAL_SPI_Transmit_IT(hspi_ad9959,RegisterData,NumberofRegisters);while(!g_ad9959_spi_tx_cplt){__NOP();}g_ad9959_spi_tx_cpltfalse;}voidHAL_SPI_TxCpltCallback(SPI_HandleTypeDef*hspi){if(hspi-Instancehspi_ad9959.Instance){HAL_GPIO_WritePin(AD9959_CS_GPIO_Port,AD9959_CS_Pin,GPIO_PIN_SET);g_ad9959_spi_tx_cplttrue;}}问题分析现象观察仔细观察实际波形图 4-6可以发现以下关键特征传输期间 CPOL 配置有效在HAL_SPI_Transmit_IT()执行期间CS 拉低后SCK 确实先保持低电平然后产生正常的时钟信号传输完成后 SCK 异常拉高数据传输完成后SCK 引脚自动变为高电平而非保持配置的低电平状态图 8SCK 空闲状态异常示意原因分析根据波形图STM32H7 系列硬件 SPI 在传输完成后不久默认会将 SCK 引脚释放到高电平状态忽略 CPOL 配置。这会导致严重问题数据采样冲突。在 SPI 模式 0CPOL0, CPHA0下从机在 SCK 上升沿采样数据。当硬件 SPI 传输完成时,SCK 从低电平跳变到高电平,此时 CS 仍为低电平,从机误将此跳变识别为有效时钟边沿导致错误采样图 9CS 拉高前的 SCK 异常跳变导致从机误采样这种时序冲突会造成数据传输错误严重影响通信可靠性。解决方案配置修改在 CubeMX 的 SPI 高级参数设置中启用Master Keep IO State选项。打开 CubeMX SPI 配置页面,展开Advanced Parameters高级参数,将Master Keep IO State从默认的Disable改为Enable图 10启用 Master Keep IO StateSTM32F1和STM32F4的硬件SPI没有Master Keep IO State配置选项