NOTE 03MCU · C
PWM 与 ADC 同步采样:把时序写进固件
从触发源、采样窗口到中断延迟,构建一个可测量、可解释的数字电源控制周期。
数字电源控制并不只是“定时执行一次算法”。真正决定采样质量的,是 PWM 边沿、功率器件开关噪声、ADC 采样窗口和中断入口之间的相对位置。
本文使用人为构造的通用时序与参数,只用于说明固件组织方法,不对应任何实际产品。
先定义可观测目标
开始写寄存器或 HAL 调用之前,先把目标写成可以用示波器验证的句子:
- ADC 由 PWM 定时器硬件触发,不依赖软件延时;
- 采样点避开开关边沿和死区变化区;
- DMA 完成后再进入控制计算;
- 控制计算必须在下一个更新点之前结束;
- 超时、过流和采样异常拥有独立路径。
这些约束一旦明确,固件结构就不再是“主循环里依次调用几个函数”,而是一条有时间边界的执行链。
一个最小执行骨架
下面的代码忽略具体芯片寄存器,只保留控制周期的边界:
typedef struct {
float vin;
float vout;
float current;
} sample_frame_t;
static volatile sample_frame_t latest_sample;
static volatile bool sample_ready;
void adc_dma_complete_isr(void)
{
latest_sample = decode_adc_buffer();
sample_ready = true;
debug_pin_set();
}
void control_tick_isr(void)
{
if (!sample_ready) {
fault_raise(FAULT_SAMPLE_TIMEOUT);
return;
}
sample_ready = false;
control_step(latest_sample);
pwm_commit_shadow_registers();
debug_pin_clear();
}
这里故意把“采样完成”和“执行控制”分成两个事件。这样既能测量 DMA 到控制入口的延迟,也能在采样未完成时进入明确的故障路径。
采样点应该放在哪里
常见做法是从 PWM 周期中心或稳定导通区开始,再根据实际波形调整。不要仅凭理论图决定最终位置,应同时观察:
- 开关节点电压;
- 电流采样放大器输出;
- ADC 触发调试引脚;
- 控制中断占用时间。
在示波器上将这些信号叠加,才能确认“代码中配置的时刻”与“硬件上真实发生的时刻”是否一致。
留给固件的余量
控制计算不应占满整个周期。除了平均执行时间,还要关注最坏路径:故障判断、限幅、模式切换和通信中断都可能扩大抖动。一个实用做法是用 GPIO 包围控制计算,并长期记录最大脉宽。
最后,采样同步的质量不是由某个漂亮的函数决定的,而是由整条触发链是否可测、可解释、可失败决定的。