# STM32定时器输入捕获测量PWM占空比:DMA与中断模式下的抖动差异及消除方法 ## 1. 引言 在电机控制、电源管理、传感器信号解析等嵌入式应用中,测量外部PWM信号的占空比是核心任务。STM32的定时器输入捕获功能能够精确记录边沿事件的时间戳,但实际测量值常伴有抖动(jitter),影响控制精度。本文将聚焦于使用**输入捕获+中断**与**输入捕获+DMA**两种模式,分析抖动产生的机理、差异,并给出消除或抑制抖动的实用方案。 ## 2. 输入捕获测量PWM的基本原理 STM32定时器(如TIM2、TIM3等)可配置为输入捕获模式,通过检测通道上的上升沿或下降沿,将当前计数器值锁存到捕获寄存器(CCRx)。测量PWM占空比通常采用**双通道捕获**或**单通道交替捕获**: - 方法A:使用两个通道,一个捕获上升沿(周期),一个捕获下降沿(高电平时间)。 - 方法B:单通道配置为上升沿和下降沿都捕获(需使用PWM输入模式),通过捕获/比较寄存器记录两次边沿。 占空比 = 高电平时间 / 周期。 ## 3. 中断模式下的抖动来源 在中断模式下,每次捕获事件触发CPU中断,软件读取CCRx值并计算。抖动主要来自: - **中断响应延迟**:从捕获事件到进入中断服务函数(ISR)存在延迟,包括硬件中断仲裁、压栈、以及可能被其他高优先级中断抢占。延迟时间通常为几十到几百个CPU周期,且不固定,导致读取CCRx时计数器可能已更新(若溢出),或计算时引入时间偏移。 - **软件处理时间**:ISR中执行多条指令(读取、计算、存储)耗时,若在捕获发生后、读取前发生定时器溢出,则读数错误。 - **优先级冲突**:若系统中有多个中断源,捕获中断可能被延迟,加剧抖动。 示例代码(中断模式): ```c // 定时器初始化(略) void TIM2_IRQHandler(void) { if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET) { TIM_ClearITPendingBit(TIM2, TIM_IT_CC1); uint32_t capture = TIM_GetCapture1(TIM2); // 读取捕获值 // 计算占空比(需处理溢出) // ... } } ``` ## 4. DMA模式的优势与抖动分析 DMA模式中,捕获事件触发DMA传输,将CCRx值自动搬运到内存,无需CPU干预。抖动主要来自: - **DMA传输延迟**:DMA请求到实际传输有固定延迟(通常几个时钟周期),但该延迟是确定性的,不随系统负载变化,因此抖动较小。 - **内存访问冲突**:若DMA与CPU同时访问总线,可能产生等待周期,但STM32的DMA控制器优先级可配置,且传输通常很快(一次32位传输约几个周期)。 - **缓冲区管理**:若使用循环缓冲区,需处理数据同步,但不会引入时间抖动。 DMA模式显著降低了软件延迟,但**抖动并未完全消除**,主要剩余抖动来自硬件本身的捕获精度(如计数器时钟分辨率)和DMA传输的确定性延迟。 ## 5. 抖动差异对比 | 模式 | 抖动来源 | 典型抖动范围 | 适用场景 | |------|----------|--------------|----------| | 中断 | 中断延迟、软件处理、优先级抢占 | 微秒级甚至更大 | 低速信号、对实时性要求不高的场合 | | DMA | 硬件捕获精度、DMA传输延迟 | 亚微秒级 | 高频PWM、高精度测量、实时控制 | 实验表明,在72MHz主频下,中断模式抖动可达±5μs,而DMA模式通常小于±0.5μs。 ## 6. 消除抖动的方法 ### 6.1 优化中断模式 - **提高中断优先级**:将捕获中断设为最高优先级,减少抢占延迟。 - **使用中断+定时器溢出中断**:在溢出中断中记录溢出次数,并在捕获中断中结合溢出次数计算完整时间戳,避免计数器回绕错误。 - **减少ISR工作量**:在ISR中仅读取捕获值并存入全局变量,计算放到主循环或低优先级任务。 ```c volatile uint32_t capture_val; volatile uint8_t capture_flag; void TIM2_IRQHandler(void) { if (TIM_GetITStatus(TIM2, TIM_IT_CC1)) { capture_val = TIM_GetCapture1(TIM2); capture_flag = 1; TIM_ClearITPendingBit(TIM2, TIM_IT_CC1); } } ``` ### 6.2 采用DMA模式 - **配置DMA循环模式**:将捕获值连续传输到数组,避免CPU干预。 - **使用双缓冲**:DMA传输到两个缓冲区,一个用于采集,一个用于处理,防止数据覆盖。 - **结合定时器溢出中断**:DMA传输捕获值,溢出中断记录溢出次数,软件综合计算。 ```c // DMA配置示例 DMA_InitTypeDef DMA_InitStructure; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&TIM2->CCR1; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)capture_buffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = BUFFER_SIZE; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_Init(DMA1_Channel2, &DMA_InitStructure); // 使能DMA DMA_Cmd(DMA1_Channel2, ENABLE); // 使能捕获DMA请求 TIM_DMACmd(TIM2, TIM_DMA_CC1, ENABLE); ``` ### 6.3 硬件滤波与时钟同步 - **输入滤波**:在捕获引脚上配置数字滤波器(如TIM_ICFilter),滤除毛刺,减少误触发。 - **使用更高分辨率时钟**:若定时器时钟为72MHz,则计数周期约13.9ns,提高时钟频率可降低量化误差。 ### 6.4 软件后处理 - **多次测量取平均**:对连续多次占空比测量值进行滤波(如移动平均),消除随机抖动。 - **中值滤波**:去除异常值,适用于噪声较大的环境。 ## 7. 注意事项 - **定时器溢出处理**:无论哪种模式,都必须处理计数器溢出,否则长时间测量会出错。建议使用溢出中断并记录溢出次数。 - **DMA缓冲区大小**:需根据PWM频率和测量周期合理设置,避免缓冲区溢出或数据未及时处理。 - **中断与DMA优先级**:若同时使用,需合理配置优先级,避免死锁或数据丢失。 - **代码可移植性**:不同STM32系列(F1、F4、H7)的DMA和定时器寄存器略有差异,需参考对应参考手册。 ## 8. 总结 在STM32定时器输入捕获测量PWM占空比时,DMA模式相比中断模式具有更低的抖动,因为其消除了软件延迟的不确定性。但DMA并非万能,仍需结合硬件滤波、溢出处理和软件滤波来达到最佳精度。开发者应根据实际应用需求(如信号频率、精度要求、CPU负载)选择合适模式,并采取相应优化措施。 通过本文的对比和消除方法,相信你能在嵌入式项目中有效提升PWM测量的稳定性。