4. 定时器/计数器接口的低功耗设计:时钟源选择、预分频器、自动重装载与单次模式、低功耗定时器(LPTIM)

定时器,可以说是嵌入式系统里最常用的外设之一。做低功耗设计时,它又成了最让人头疼的家伙。

为什么?因为传统定时器太“耗电”了。你想想看,它需要主时钟一直跑着,哪怕CPU睡了,定时器还得醒着。这不合理。

我早年做一款电池供电的传感器节点,就吃过这个亏。当时用普通TIM做周期性唤醒,结果待机电流比预期高了整整一个数量级。查了两天才发现——定时器时钟源没选对,预分频器配置也不合理。从那以后,我对定时器的低功耗设计就格外上心。

4.1 时钟源选择:低功耗的第一道关卡

定时器要工作,首先得有时钟。但时钟源的选择,直接决定了功耗基线。

核心原则:能用低速时钟,就别用高速时钟。能关掉主时钟,就用独立时钟源。

常见的定时器时钟源有这么几种:

时钟源 典型频率 功耗等级 适用场景
系统主时钟(HCLK) 数十~数百MHz 高 高精度PWM、高频计数
内部低速RC(LSI) 32~40kHz 低 低功耗定时器、看门狗
外部低速晶振(LSE) 32.768kHz 极低 RTC、精准定时唤醒
内部高速RC(HSI) 8~16MHz 中 普通定时任务

我个人的习惯是:只要定时周期在毫秒级以上,优先考虑LSI或LSE。别小看这几十kHz的差别,在深度睡眠模式下,一个用HCLK的定时器可能吃掉几百微安,而用LSE的LPTIM只需要几微安。

小技巧:有些MCU允许定时器在休眠时切换到LSI时钟,醒来后再切回HCLK。这种“动态时钟切换”功能,既保证了低功耗,又不牺牲唤醒后的精度。

4.2 预分频器:精度与功耗的平衡术

预分频器,说白了就是给时钟降频。但怎么降、降多少,这里面有讲究。

预分频器的本质是一个计数器,它对输入时钟进行分频,产生一个更慢的时钟给定时器核心使用。分频系数通常是2的幂次(如1、2、4、8…),也有些芯片支持连续分频。

举个例子:

// 假设时钟源为 LSI,32kHz
// 目标:产生 1Hz 的定时中断

// 方案A:不分频,直接计数
// 需要计数 32000 次,计数器位宽需 ≥ 16位
TIM->PSC = 0;        // 预分频系数 = 1
TIM->ARR = 31999;    // 自动重装载值

// 方案B:分频后计数
// 先分频到 1kHz,再计数 1000 次
TIM->PSC = 31;       // 预分频系数 = 32
TIM->ARR = 999;      // 自动重装载值

两种方案都能实现1Hz中断,但区别在哪?

  • 方案A:计数器跑得快(32kHz),每次计数功耗略高,但ARR值大,适合长周期。
  • 方案B:计数器跑得慢(1kHz),每次计数功耗低,但ARR值小,适合短周期。

我在项目中遇到过一个问题:用方案A做10秒定时,ARR需要设到319999,结果计数器溢出了一次,定时不准了。后来改成方案B,先分频到100Hz,再计1000次,问题就解决了。

注意:预分频器本身也是计数器,它也在耗电。分频系数越大,预分频器翻转次数越多,功耗反而可能上升。所以不是分频越大越好,要实测权衡。

4.3 自动重装载与单次模式:两种典型工作方式

定时器的两种工作模式,对应着不同的低功耗策略。

4.3.1 自动重装载模式

这是最常用的模式。计数器从0计数到ARR值,产生事件,然后自动重置为0,继续下一轮。

适合周期性任务,比如:

  • 周期性唤醒CPU检查传感器
  • 产生固定频率的PWM波
  • 系统心跳节拍

低功耗要点:尽量让定时器在休眠期间独立运行,CPU只在事件发生时醒来。别让CPU陪着定时器一起数数。

4.3.2 单次模式(One-Shot)

计数器只跑一轮,产生事件后就停止。适合一次性延时或超时检测。

我特别喜欢单次模式做“延时关机”——按下按键后,定时器启动,5秒后自动切断电源。这期间CPU可以睡大觉。

// 单次模式配置示例(STM32 LPTIM)
LPTIM->CFGR |= LPTIM_CFGR_COUNTMODE;  // 设置为单次模式
LPTIM->ARR = 4999;                     // 5秒(假设时钟1kHz)
LPTIM->CR |= LPTIM_CR_ENABLE;          // 启动定时器
// 定时器开始计数,CPU可以进入低功耗模式
// 5秒后产生中断,唤醒CPU

经验之谈:单次模式配合低功耗定时器,是做“事件驱动型”低功耗系统的利器。我曾经用这个组合,把一款门磁传感器的待机功耗降到了1.5µA以下。

4.4 低功耗定时器(LPTIM):专为省电而生

普通定时器在低功耗模式下往往无法工作,或者需要额外配置。于是芯片厂商专门设计了低功耗定时器(LPTIM)。

LPTIM和普通TIM有什么区别?我整理了一张表:

特性 普通TIM LPTIM
时钟源 通常依赖HCLK 支持LSI/LSE/外部时钟
低功耗模式 多数模式下停止 可在Stop/Standby下运行
功耗 数百µA~数mA 几µA~几十µA
位宽 16位或32位 通常16位
功能 丰富(PWM/捕获/比较) 基础(定时/计数/唤醒)

LPTIM的设计哲学很明确:放弃花哨功能,换取极致低功耗。

它通常具备以下特性:

  • 独立时钟域:即使系统主时钟停了,LPTIM依然可以运行
  • 异步唤醒:定时事件可以直接将MCU从深度睡眠中唤醒
  • 输入脉冲计数:可以在休眠状态下统计外部脉冲
  • 超低功耗设计:内部电路经过专门优化,静态电流极低

我曾经用LPTIM做过一个“超长待机”项目:设备每30秒唤醒一次,采集数据后继续休眠。用普通TIM,待机电流约12µA;换成LPTIM后,降到了2.3µA。电池寿命从3个月延长到了18个月。

避坑指南:LPTIM虽然省电,但精度有限。LSI的温漂可能达到±10%,如果你需要高精度定时,还是得用LSE或者定期校准。我曾经因为没考虑温漂,导致设备在高温环境下唤醒周期偏差了15%,差点误事。

4.5 知识结构总览

下面这张图,把本章的核心知识点串起来了:

定时器/计数器低功耗设计知识结构图 定时器/计数器低功耗设计知识结构 定时器低功耗设计 时钟源选择 预分频器 工作模式 低功耗定时器 HCLK / HSI LSI / LSE 外部时钟输入 分频系数选择 精度 vs 功耗 动态切换 自动重装载 单次模式 PWM / 捕获 独立时钟域 异步唤醒 脉冲计数 核心设计原则 ① 优先选择低速独立时钟源 ② 合理配置预分频器平衡精度与功耗 ③ 善用单次模式减少无效计数 ④ 低功耗场景首选LPTIM

4.6 实战建议

说了这么多,最后给几条实在的建议:

  1. 先看芯片手册:确认你的MCU有没有LPTIM,支持哪些时钟源。别等到画板子了才发现没有。
  2. 实测功耗:理论计算和实际测量往往有差距。我习惯在原型阶段就用电流探头测一下定时器单独工作时的功耗。
  3. 预留校准接口:如果用了LSI,最好留一个校准通道。温度变化时,可以通过RTC或者外部晶振来修正定时参数。
  4. 别过度设计:如果系统只需要秒级定时,别用32位定时器。16位LPTIM加合适的分频,完全够用。

嗯,定时器这块就聊到这儿。记住一句话:低功耗设计不是把功能做少,而是把每一分电都用在刀刃上。