【嵌入式面试】STM32 定时器高频面试题
【嵌入式面试】STM32 定时器高频面试题
定时器是 STM32 面试中出镜率最高的外设之一,从时基单元、PWM 到输入捕获、编码器接口,几乎每个嵌入式岗位都会问到。本文整理了定时器方向的高频面试题与参考答案,帮助你从"会用库函数"进阶到"讲得清原理"。
一、定时器分类与时基单元
1. STM32 定时器分为哪几类?有什么区别?
按功能可分为三类:基本定时器(TIM6/TIM7)只有时基单元,只能定时中断和触发 DAC,没有输入输出通道;通用定时器(TIM2~TIM5)在时基单元基础上增加输入捕获、输出比较、PWM、编码器接口等功能,是考察重点;高级定时器(TIM1/TIM8)再增加互补输出、死区生成、刹车输入(Break)与重复计数器,用于电机控制等需要安全保护的场合。一句话记忆:基本=只能定时,通用=能输入输出,高级=通用+电机控制专用功能。
2. 什么是时基单元?PSC、ARR、CNT 分别是什么?
时基单元由预分频器 PSC、自动重装载寄存器 ARR、计数器 CNT 组成:PSC 对时钟源分频,决定计数频率(f计数 = fCLK/(PSC+1));CNT 是当前计数值;ARR 是计数周期目标值。向上计数模式下,CNT 从 0 递增到 ARR 后溢出,产生更新事件,然后回到 0 重新计数。三者共同决定定时器的"心跳"节奏。
3. 定时时间怎么计算?为什么公式里 PSC 和 ARR 都要加 1?
定时时间公式:T = (PSC+1) × (ARR+1) / fCLK(向上计数,fCLK 为定时器输入时钟)。因为预分频器和计数器都是从 0 开始计数的,实际参与分频/计数的值是 PSC+1 和 ARR+1,所以都要加 1。例如 72MHz 下产生 1ms 定时:PSC=71 得到 1MHz 计数频率,ARR=999 计满 1000 个计数周期,T=1000×1µs=1ms。简单记:PSC 决定每个计数周期多长,ARR 决定一共数多少个。
4. 16 位定时器最大能定时多久?如何扩展?
PSC、ARR 都是 16 位(0~65535),72MHz 下最大定时 ≈ (65535+1)×(65535+1)/72MHz ≈ 59.6 秒。扩展方法有三种:改用 32 位计数器的定时器(F1 上 TIM2/TIM5 的 CNT/ARR 为 32 位);用定时器级联(主定时器更新事件作为从定时器时钟)扩大计数范围;或用定时器中断 + 软件计数(如 1ms 中断累加 1000 次得到 1s)。
5. 修改 PSC/ARR 后是立即生效吗?
默认情况下 ARR 和 PSC 都有预装载缓冲,写入的新值要等到下一次更新事件才真正生效。所以改完 ARR 后往往需要软件触发一次更新事件(或等自然溢出),否则定时参数不变——这是"我改了 ARR 但没效果"的常见原因。若关闭预装载(ARPE=0),则写入立即生效。
二、计数模式与 PWM、输出比较
6. 向上、向下、中央对齐三种计数模式有什么区别?
向上计数:CNT 从 0 递增到 ARR 溢出,最常用;向下计数:CNT 从 ARR 递减到 0 溢出;中央对齐计数:CNT 在 0 与 ARR 之间来回递增递减(0→ARR→0),上溢/下溢都产生更新事件(由 CMS 位选择),常用于生成对称 PWM。注意中央对齐下一个完整 PWM 周期包含上溢+下溢两次计数,所以 PWM 频率 = fCLK / ((PSC+1)×(ARR+1)×2)。
7. PWM 输出的原理是什么?占空比怎么计算?
PWM 通过输出比较实现:计数器 CNT 与比较寄存器 CCR 不断比较,PWM 模式 1 下 CNT<CCR 输出有效电平、CNT≥CCR 输出无效电平。向上计数时占空比 Duty = CCR/(ARR+1),PWM 频率 f = fCLK/((PSC+1)×(ARR+1))。例:72MHz 下 PSC=71、ARR=999、CCR=500,得到 1kHz、占空比 50% 的方波;分辨率 = 1/(ARR+1),ARR 越大占空比调节越精细。
8. 如何输出占空比 0% 和 100% 的 PWM?
令 CCR=0 输出恒为无效电平(约 0%);令 CCR≥ARR+1(即 CCR 大于 ARR)输出恒为有效电平(约 100%)。工程中常用这种方式做"软开关"(如电机/灯的控制使能),而不必真正切断 PWM 通道。
9. 输出比较是什么?与 PWM 是什么关系?
输出比较:定时器把 CNT 与 CCR 比较,满足条件时产生比较事件,可配置为翻转输出、强制高/低或触发中断。PWM 就是输出比较最典型的应用——把比较结果映射为周期性的高低电平;此外输出比较还能做精确延时、定时触发 ADC 等。可以说:PWM 是输出比较的一种用法。
10. 高级定时器的互补输出和死区是做什么的?
高级定时器(TIM1/TIM8)可同时输出互补的两路 PWM(如 CH1 与 CH1N),并在两路切换之间插入可编程的死区时间:先关断一路、延时后再导通另一路,防止 H 桥/逆变器中上下桥臂同时导通短路。死区宽度由寄存器配置,是电机驱动、电源变换方向的高频考点。
三、输入捕获与编码器接口
11. 输入捕获的原理是什么?如何测量脉宽?
输入捕获:引脚出现指定边沿(上升/下降)时,硬件自动把当前 CNT 值锁存到捕获寄存器 CCxR 并置捕获标志,软件只需读值。测脉宽:上升沿捕获 t1,下降沿捕获 t2,脉宽 = (t2−t1) × 单个计数周期(注意处理 CNT 溢出)。因为锁存由硬件在边沿瞬间完成,不受中断响应延迟影响,测量精度高。
12. 如何用输入捕获测量信号频率?
测周期再取倒数:连续捕获两次同一边沿(如两个上升沿)得到 Δt,频率 = 1/Δt。若两次捕获之间 CNT 发生了溢出,必须通过更新中断统计溢出次数把时间补回去,否则结果错误。也可用 PWM 输入模式(PWMI)一次性同时得到频率与占空比。
13. 什么是 PWM 输入模式(PWMI)?有什么好处?
PWMI 让两个捕获通道配合:一个通道测周期(连续两个上升沿),另一个通道测脉宽(上升沿到下降沿),一次配置就能同时得到信号的频率与占空比。常用于 RC 遥控接收机信号解析等需要快速获得频率+占空比的场景。
14. 输入捕获时 16 位计数器溢出了怎么办?
16 位计数器到 65535 后会回绕,捕获差值会算错。处理方法是开启更新中断,每次溢出在中断里累加溢出次数,最终时间 = 溢出次数 × 溢出周期 + 当前捕获差值(即"32 位拼接"思路)。也可以直接选用 32 位计数器定时器(TIM2/TIM5),或改用外部计数/分频降低溢出频率。
15. 编码器接口模式是怎么工作的?
定时器编码器模式(SMS=001/010/011)直接连接正交编码器的 A、B 两相(接 TI1/TI2):硬件根据两路信号的相位关系自动判断旋转方向,并在每个边沿对 CNT 自动加/减 1,CNT 值就是位置。支持 1x/2x/4x 倍频(每个边沿都计数),无需软件轮询,广泛用于电机测速与位置检测。
四、更新事件、级联与定时应用
16. 更新事件(UEV)是什么?更新中断的流程?
计数器溢出(向上计数到 ARR、向下到 0、或中央对齐的上/下溢)时产生更新事件 UEV,硬件置 UIF 标志。使能更新中断后进入中断服务函数,处理完必须软件清除 UIF,否则会反复进中断。更新事件还可触发 DMA(定时自动搬运数据)和 DAC(如基本定时器触发 DAC 输出波形)。
17. 什么是定时器级联?为什么要级联?
通过主从模式,把一个定时器的更新事件/触发输出(TRGO)接到另一个定时器的从输入(ITRx),让从定时器以主定时器的更新事件作为计数时钟。级联可以突破单个 16 位定时器的计数范围(两个级联等效更大位宽),或实现更灵活的分频组合与同步触发,是"用普通定时器干高级活"的典型手法。
18. 如何用定时器产生 1ms 和 1s 定时?
按公式 T=(PSC+1)×(ARR+1)/fCLK:1ms(72MHz)取 PSC=71 → 计数频率 1MHz,ARR=999 → 计 1000 个周期,T=1ms;1s 有两种方案:一是 PSC=7199 → 计数频率 10kHz,ARR=9999 → 计 10000 个周期,T=1s;二是用 1ms 中断在软件里累加 1000 次得到 1s(更省资源,也是裸机/RTOS 常见的软件定时思路)。
19. 定时器测频/测脉宽的误差来源有哪些?如何提高精度?
误差主要来自:时钟源精度(晶振或 RC 振荡器偏差)、信号边沿抖动、±1 个计数周期的量化误差、以及溢出处理遗漏。工程权衡:测高频用计数法(统计一段时间内的脉冲数)、测低频用测周期法(测一个周期的时长)、多次测量取平均可抑制随机误差——答出这个"低频测周期、高频测计数"的权衡是加分项。

