PWM 与比较匹配中断

← 中断总览 | ← 主页


CMP 比较匹配中断

定时器模块包含一个自由运行的计数器(CNT)和一个或多个比较寄存器(Compare Register,CMP)。当 CNT == CMP 时,硬件触发 比较匹配事件,可配置为产生中断。这是定时器中断(PWM、输出比较、输入捕获等)的通用底层机制。

计数器值 CNT
     │
     ▼
  ┌──────────────────────────────────────────┐
  │  0 ──────────────── CMP ──────── ARR     │
  │                      ↑                   │
  │               比较匹配,触发中断           │
  └──────────────────────────────────────────┘
  • ARR(Auto-Reload Register):定时器周期,CNT 到达 ARR 后归零(或反向计数)。
  • CMP / CCR(Capture/Compare Register):比较值,CNT 到达此值时触发事件或中断。
  • 每个通道通常有独立的 CMP 寄存器,可产生独立的中断。

中心对齐模式下的双 CMP 中断(每通道两个比较点)

在四开关 Buck-Boost 等功率变换器中,PWM 采用中心对齐(上下计数)模式,每个通道配置两个比较寄存器:

struct PWMDutyVariable
{
    bool     buckBoostMode = false;
    float    dutyA         = 0.0f;
    float    dutyB         = 0.0f;
    uint16_t ACMP1         = 8000;   // 通道A — 上升沿阶段触发
    uint16_t ACMP3         = 8000;   // 通道A — 下降沿阶段触发
    uint16_t BCMP1         = 8000;   // 通道B — 上升沿阶段触发
    uint16_t BCMP3         = 8000;   // 通道B — 下降沿阶段触发
};

计数器与双 CMP 的时序关系

  • 计数器从 0 上升到 ARR,再下降回 0,构成一个完整 PWM 周期。
  • CMP1:CNT 上升过程中与比较值相等时触发,对应 PWM 输出的前半周期事件
  • CMP3:CNT 下降过程中与同一(或不同)比较值相等时触发,对应后半周期事件
  • 每周期共触发 2 次 CMP 中断(上升 + 下降各一次)。

占空比与 CMP 值的关系

设 ARR = 8000(对应 100% 周期),占空比

对称模式下 CMP1 == CMP3;非对称模式下两者不同,可产生相移或不对称波形。

双 CMP 中断的典型用途

中断点触发时机典型操作
CMP1(上升沿)PWM 高电平开始前更新下一周期占空比、触发 ADC 采样
CMP3(下降沿)PWM 高电平结束后读取 ADC 结果、执行控制算法
OVF(ARR 顶点)计数器到达峰值同步多路 PWM、周期性保护检测

CMP 值更新时机

双 CMP 模式下,必须在 OVF 或 CMP 中断内更新 CMP 寄存器,避免在计数器运行中途写入导致毛刺:

// 在 OVF 中断(计数器归零/到顶)时统一更新,保证下一周期生效
void PWM_OVF_IRQHandler(void)
{
    // 根据控制算法计算新占空比
    float dutyA = ControlLoop_GetDutyA();
    float dutyB = ControlLoop_GetDutyB();
 
    // 对称模式:CMP1 == CMP3
    uint16_t cmpA = (uint16_t)(ARR * (1.0f - dutyA));
    uint16_t cmpB = (uint16_t)(ARR * (1.0f - dutyB));
 
    PWM_SetCMP(CH_A, CMP1, cmpA);
    PWM_SetCMP(CH_A, CMP3, cmpA);
    PWM_SetCMP(CH_B, CMP1, cmpB);
    PWM_SetCMP(CH_B, CMP3, cmpB);
}

📎 异常进入/退出时 SP、LR、PC 寄存器的硬件行为(自动压栈、EXC_RETURN 等)详见 SP 寄存器笔记