输出比较与输入捕获
笔记 / 嵌入式
引言
定时器的基本计数功能提供时间基准,输出比较和输入捕获负责与外部信号交互:输出比较产生信号,输入捕获测量信号。PWM、频率计、超声波测距等应用都建立在这两个功能之上。
一、核心概念:CNT 与 CCR
理解输出比较和输入捕获,关键在于两个寄存器的关系:
| 寄存器 | 含义 | 在 IC 中 | 在 OC 中 |
|---|---|---|---|
| CNT | 计数器 | 计时基准 | 计时基准 |
| CCR | 捕获/比较寄存器 | 保存 CNT 的当前值 | 与 CNT 比较,匹配时触发动作 |
两者的区别在触发方向:输入捕获在外部信号边沿到来时,把 CNT 的当前值存入 CCR;输出比较在 CNT 计数值与 CCR 相等时,触发预先配置的动作。
二、输入捕获(Input Capture)
2.1 工作原理
┌─────── 捕获上升沿 ───────┐
│ │
外部信号: ────┘ └───────
│ │
CNT值: ... 100 ... 200 ... 300 ... 400 ... 500 ...
↑ ↑
CCR=100 CCR=500
脉冲宽度 = 500 - 100 = 400 个计数周期
工作流程:
- 配置通道为输入捕获模式,选择触发边沿(上升沿 / 下降沿 / 双边沿)
- 当指定边沿到来时,硬件自动把当前 CNT 的值复制到 CCR
- 连续捕获两次,两次 CCR 的差值就是两个边沿之间的时间
- 配合计数频率换算出实际时间:
时间 = 差值 × 计数周期
这相当于用一个持续运行的计时器,在两个事件发生的时刻各记录一次读数,再相减。
2.2 测量频率
频率测量常用两次上升沿捕获法:
f_signal = f_cnt / (CCR2 - CCR1)
其中 f_cnt 是 CNT 的计数频率 = TIM_CLK / (PSC + 1)
2.3 典型应用
| 应用 | 说明 |
|---|---|
| 频率计 | 测量外部信号的频率 |
| 占空比测量 | 同时测量 PWM 信号的高电平与周期 |
| 红外遥控解码 | 测量编码脉冲的宽度 |
| 超声波测距 | 测量 Echo 引脚高电平持续时间 |
| 编码器测速 | 通过捕获正交编码器脉冲测量转速 |
2.4 HAL 配置示例
TIM_IC_InitTypeDef sConfigIC = {0};
sConfigIC.ICPolarity = TIM_ICPOLARITY_RISING; // 上升沿捕获
sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI; // 直接映射到 TIx
sConfigIC.ICPrescaler = TIM_ICPSC_DIV1; // 不分频
sConfigIC.ICFilter = 0x0; // 数字滤波
HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_1);
// 启动输入捕获中断
HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);
三、输出比较(Output Compare)
3.1 工作原理
CNT: 0 ──→ 30 ──→ 60 ──→ 90 ──→ ARR ──→ 0 ──→ ...
↑
CNT == CCR (假设CCR=30)
│
┌────┴────┐
│ 触发动作 │ → 翻转/置高/置低/中断
└─────────┘
CNT 与 CCR 的比较在硬件上就是一个数字比较器:两者相等时输出匹配信号,触发预先配置的动作。
3.2 八种输出比较模式
| 模式 | 匹配时行为 | 典型用途 |
|---|---|---|
| 冻结 (Frozen) | 输出保持不变 | 暂停 PWM 输出 |
| 匹配时置有效电平 | 输出置高 | 单次脉冲 |
| 匹配时置无效电平 | 输出置低 | 单次脉冲 |
| 匹配时翻转 (Toggle) | 电平取反 | 生成 50% 占空比方波 |
| 强制无效电平 | 强制输出低 | 强制停机 |
| 强制有效电平 | 强制输出高 | 强制输出 |
| PWM 模式 1 | CNT < CCR 高, CNT ≥ CCR 低 | 最常用的 PWM 输出 |
| PWM 模式 2 | CNT < CCR 低, CNT ≥ CCR 高 | PWM 模式 1 的反相版本 |
3.3 典型应用
| 应用 | 说明 |
|---|---|
| LED 调光 | 改变 PWM 占空比控制亮度 |
| 电机调速 | PWM 控制直流电机转速 |
| 舵机控制 | 用特定脉宽控制角度 |
| 生成参考方波 | Toggle 模式生成 50% 占空比方波 |
| 外设同步信号 | 匹配时触发 ADC 采样 / DMA 传输 |
四、输入捕获与输出比较对比
| 维度 | 输入捕获 (IC) | 输出比较 (OC) |
|---|---|---|
| 数据流向 | 外部 → MCU(测量外部信号) | MCU → 外部(产生信号) |
| CNT 与 CCR 的关系 | 边沿到来时,CNT → CCR | CNT == CCR 时触发动作 |
| 引脚方向 | 输入 | 输出(复用推挽) |
| 核心用途 | 测频率、周期、脉宽、占空比 | 输出 PWM、方波、脉冲 |
| 中断事件 | 捕获中断 | 比较匹配中断 |
| 共用资源 | 同一通道同一时刻只能配置为 IC 或 OC |
五、常见问题与排查
CNT 溢出处理(输入捕获)
当被测信号周期很长时,CNT 会在两次捕获之间溢出,需要统计溢出次数:
实际时间 = 溢出次数 × (ARR + 1) + 最后一次 CCR 值
溢出计数在更新中断中累加。
PWM 输出无波形
常见原因:
- GPIO 未配置为复用推挽输出
- 未调用
HAL_TIM_PWM_Start()启动输出 - 高级定时器(TIM1/TIM8)未使能主输出,需设置 MOE 位
- 时钟未使能
总结
输出比较和输入捕获是定时器使用最广的两个功能:输入捕获测量外部信号,输出比较产生外部信号。两者都围绕 CNT 与 CCR 的关系工作——捕获是在边沿到来时把 CNT 写入 CCR,比较是在 CNT 等于 CCR 时触发动作。定时器约 80% 的应用场景都建立在这两种关系之上。
输出比较最常见的应用形态是 PWM。