[STM32F7] 中断服务程序抖动

[复制链接]
79|16
Hitomi22 发表于 2026-8-22 22:26 | 显示全部楼层 |阅读模式

使用 STM32F767 Nucleo‑144 开发板。在 CubeIDE 中将 SPI1 配置为 I2S1 输入,通过 DMA2/Stream0 将数据搬运至一个简短的 8×16 位环形缓冲区。SPI1 时钟约为 3MHz。我配置了 HAL_I2S_RxHalfCpltCallback () 与 HAL_I2S_RxCpltCallback () 回调函数。在两个回调函数中各翻转一次 GPIO,得到约 23.8kHz 的方波。

但是该方波存在明显抖动。存在 100ns 量级的固定抖动;在部分时间段内,信号的占空比会出现约 330ns 的偏移,持续大约一秒。330ns 恰好是我所用 3MHz 时钟的周期倒数。


我曾精简 HAL_DMA_IRQHandler (),只保留我项目必需的代码,但抖动没有改善。我也调整过 NVIC 优先级,同样无效。

如何消除该抖动?

Bowclad 发表于 2026-8-23 13:55 | 显示全部楼层
检查 DMA2/Stream0 的优先级配置,确保它高于其他中断,可能优先级设置不够高导致中断响应延迟。
spicy 发表于 2026-8-25 14:24 | 显示全部楼层
你观察到的330ns偏移正好等于3MHz时钟周期,这强烈说明抖动来源是SPI时钟与DMA传输之间的相位或同步问题,而不是中断响应延迟。
classroom 发表于 2026-8-25 14:24 | 显示全部楼层
回调函数里翻转GPIO这个操作本身就会引入抖动,因为GPIO翻转指令执行时间受流水线和总线矩阵占用影响,不是固定周期执行的。
cr315 发表于 2026-8-25 16:48 | 显示全部楼层
你精简了HAL_DMA_IRQHandler但没改善,说明抖动根源不在DMA中断处理函数内部的代码路径长短,而可能在DMA传输完成事件的触发时机本身就有波动。
duo点 发表于 2026-8-25 19:09 | 显示全部楼层
环形缓冲区只有8个16位样本,这意味着每8个样本就触发一次中断,中断频率高达23.8kHz,这么频繁的中断下CPU总线访问冲突不可避免会产生抖动。
flycamelaaa 发表于 2026-8-25 21:57 | 显示全部楼层
检查一下你的DMA配置里是不是用了循环模式,如果配置为单次模式再手动重载,重载动作的时间不确定性也会直接反映到GPIO翻转时刻。
jcky001 发表于 2026-8-26 09:26 | 显示全部楼层
3MHz的SPI时钟下,每个位周期约333ns,你看到的330ns偏移说明问题可能出在I2S帧同步信号与DMA传输完成标志之间的同步偏差上。
onlycook 发表于 2026-8-26 10:54 | 显示全部楼层
NVIC优先级调整没效果,说明不是中断被更高优先级打断导致的延迟,而是中断触发源本身就不是严格等间隔产生的。
powerantone 发表于 2026-8-26 13:40 | 显示全部楼层
你是在半完成和完成两个回调里各翻转一次GPIO,产生23.8kHz方波,但这两个回调的执行时刻分别对应DMA读取到缓冲区中间和末尾,它们之间的时间间隔受缓冲区填充速率影响,而填充速率来自外部I2S时钟,外部时钟可能有微小漂移。
probedog 发表于 2026-8-26 16:11 | 显示全部楼层
建议用定时器触发DMA传输而不是依赖SPI硬件标志,把DMA请求改为定时器触发,这样可以把抖动从外设时钟域转移到系统时钟域来改善。
solty 发表于 2026-8-26 18:34 | 显示全部楼层
抖动还可能是Cache一致性导致的,STM32F7有数据和指令Cache,DMA直接访问SRAM时不经过Cache,CPU读取标志位可能读到的是过期的缓存值。
stormwind123 发表于 2026-8-26 21:01 | 显示全部楼层
去掉HAL库的回调函数,直接写在DMA中断向量对应的裸中断服务程序里,省去HAL层的那几层函数调用和判断逻辑,虽然不一定解决抖动但能排除软件延迟的干扰。
七毛钱 发表于 2026-8-26 22:29 | 显示全部楼层
23.8kHz的中断频率下,CPU还要处理总线矩阵对SPI和DMA同时访问SRAM的仲裁延迟,每次仲裁结果不同就会导致中断响应时刻有几纳秒到几百纳秒的随机变化。
今天会画卧蚕吗 发表于 2026-8-27 10:46 | 显示全部楼层
你可以把环形缓冲区扩大到128或256个样本,这样中断频率降到原来的十几分之一,中断竞争减少后抖动通常会有明显改善,这是最直接的验证方法。
内政奇才 发表于 2026-8-27 14:58 | 显示全部楼层
示波器测到的抖动中100ns是固定值,这部分可能来自AHB总线到APB外设之间的同步桥延迟,这个延迟本身是固定的但会在每个中断周期重复出现。
又见江南雨 发表于 2026-8-27 19:10 | 显示全部楼层
如果外部I2S时钟源不是来自芯片内部PLL而是外部晶振或外部主时钟,那么时钟源本身的相位噪声和抖动也会直接传递到DMA的传输完成时刻上,这部分靠软件***消除不了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

198

主题

201

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部
0