STM8S 低功耗怎么配:4 种模式与 3 个时钟源,7 步把唤醒链做对

电池节点的休眠电流降不下来,换电池只是治标。结论先给:STM8S 的功耗由低功耗模式、主时钟源、停机期间 FLASH 是否掉电、AWU 预分频四件事共同决定,任何一处配错,实测值都不会落在设计值上。

2026-10-26
低功耗设计STM8S自动唤醒时钟管理电池供电嵌入式

水表、井盖、温湿度变送器这类电池节点,硬件定型之后最常见的抱怨是"休眠电流怎么都降不下去"。换电池、加大容量都只是治标。结论先给:STM8S 的功耗不是靠把 WFI 换成 HALT 就能降下来的,它由四件事共同决定——低功耗模式、主时钟源、停机期间 FLASH 是否掉电、以及 AWU 的预分频。这四块在 RM0016 里分别落在电源管理、时钟控制、FLASH 和自动唤醒四章,任何一处配错,实测平均电流都不会落在你算出来的那个数上。

一、四种模式:差别在"谁还在供电"

RM0016 把低功耗模式列成四行,很多人只记得"等待"和"停机"两个名字,实际上活跃停机被拆成了快速、慢速两档,而这两档的功耗和唤醒时间差一个量级。

模式主电压调节器振荡器CPU / 外设可用唤醒源
等待 Wait开开CPU 关,外设按门控状态运行所有内部中断(含 AWU)、外部中断、复位
快速活跃停机开仅 LSI(或 HSE)CPU 关,外设关AWU 或外部中断、复位
慢速活跃停机关(低电压调节器仍在工作)仅 LSICPU 关,外设关AWU 或外部中断、复位
停机 Halt关(低电压调节器仍在工作)关CPU 关,外设关仅外部中断、复位

手册用 -、--、---、---- 标注功耗级别,越往下的行功耗越低,代价是唤醒源越来越少。选择逻辑其实只有一句话:需要定时自己醒来,就用活跃停机;只能靠外部事件唤醒,才用停机。停机模式下所有由 fMASTER 提供时钟的模块都停了,AWU 计数器也不走,指望它定时醒来是配不出来的。

进入方式也不同:等待模式执行 WFI,停机与活跃停机都执行 HALT 指令。活跃停机必须先使能 AWU,再执行 HALT,计数器才会在进入低功耗后开始计数;这一点顺序写反了,现象就是"睡了不醒"。

二、三个时钟源:HSI/8 才是默认状态

复位后时钟控制器自动选择 HSI 的 8 分频作为主时钟,手册给的理由是启动快、且在较差的 VDD 条件下也能安全启动。也就是说,上电后芯片并不在 16MHz 全速运行,要全速得自己切过去——反过来,做低功耗时这个默认值反而是有利起点。

时钟源频率启动与精度低功耗相关用法
HSE 外部晶体1 ~ 24MHz(外部有源时钟最高 24MHz)精度高,启动默认插入 2048 个振荡器周期延迟,可用选项字节 HSECNT 缩短经 HSEPRSC 分频可输出 128kHz,作为 AWU 与独立看门狗的时钟源
HSI 内部 RC16MHz,分频因子 1 ~ 8无需外部器件,启动比 HSE 快,精度低于晶体唤醒后接管主时钟,省掉等待晶振稳定的时间
LSI 内部 RC128kHz出厂已校准,不能再校准,全温范围离散度约 ±12.5%活跃停机期间驱动 AWU 与独立看门狗,是"守夜人"时钟

运行模式下想省电还有两个手段:写 CLK_CKDIVR 的 CPUDIV[2:0] 把 fCPU 降下来(共 7 档,1 到 128 中 2 的幂),以及用外设时钟门控关掉 ADC、I2C、SPI、TIM4 ~ TIM1 这些当前不用的模块。注意 CPUDIV 只影响 CPU 和窗口看门狗,由 fMASTER 供时钟的外设并不跟着降速——想省外设的功耗,只能靠门控。

三、FLASH 掉电位:纳秒和微安的交换

这一条最容易被忽略。默认情况下芯片进入停机后 FLASH 处于掉电状态,漏电流可以忽略,但唤醒需要几微秒;把 FLASH_CR1 的 HALT 位置 1,FLASH 在停机期间保持等待状态,唤醒时间降到几纳秒,代价是功耗增加到几微安。这就是一个明确的取舍:唤醒频繁就买时间,唤醒稀疏就买电流。

活跃停机也有同一个开关,只是取向相反:按 FLASH_CR1 的位定义,AHALT 清 0 时 FLASH 在活跃停机期间断电,休眠电流更低,但唤醒时间增加到微秒级;置 1 则保持运行、换更快的唤醒。需要说明的是,手册第 9.4.2 节的文字叙述与寄存器位定义的方向并不一致,落地时以寄存器位定义为准,并在样机上用电流表实测确认哪一种配置真的省电。

与 FLASH 配套的还有两个时钟寄存器位。REGAH 置 1 后,进入活跃停机时主电压调节器自动关闭,内核改由低功耗调节器供电,此时只有 LSI 可用——HSE 对低功耗调节器来说电流太大。所以"REGAH 打开 + 用 HSE 分频喂 AWU"是自相矛盾的组合,配下去的结果是唤醒异常。FHWU 置 1 则让芯片从停机或活跃停机唤醒时,HSI 自动被设为主时钟,省掉一次时钟切换。

四、AWU 间隔:算出来,别试出来

自动唤醒的间隔由两处决定:AWU_TBR 的 AWUTB[3:0] 选时间基准(共 15 档不重叠区间),AWU_APR 的 APR[5:0] 给异步分频值。手册给出的换算是 T = 2^n × APRDIV / fLS,其中 n 由 AWUTB 决定,fLS 是低速时钟频率。

这里有个必须记住的偏移:APR 寄存器值与 APRDIV 不是等号关系。00h 对应 APRDIV = 2,0Eh 对应 16,3Eh 对应 64,也就是寄存器值 = APRDIV − 2;而复位值 3Fh 是禁用值,写进去预分频器根本不计数。

手册表 23 的例子可以直接拿来套:fLS = 128kHz、目标 78.5ms,先算理想分频值 0.0785 × 128000 ÷ 256 ≈ 39.25,取整 39,于是 APR 写 0x25(37),实际间隔 256 × 39 ÷ 128000 = 78ms。如果直接往 APR 里写 39,得到的是 41 分频,间隔会变成 82ms,每天累计的偏差就是这么来的。

还有两件事:LSI 全温离散度约 ±12.5%,对时间精度有要求的场合,应先用 AWU_CSR 的 MSR 位把 LSI 接到 TIM3 的输入捕捉 1 上测出实际频率,再回填 APR;不使用 AWU 时,务必把 AWUTB 清成 0000,否则活跃停机的电流降不下来。

五、七步把唤醒链配完

把上面四块串起来,落地顺序就是七步:定模式 → 定主时钟 → 定分频与门控 → 定 FLASH 掉电位 → 算 AWU → 进 HALT → 复测。其中第六步之前要先关中断,醒来后第一件事是读 AWU_CSR 清 AWUF 标志,否则会立刻再次进入中断。

/* STM8S 活跃停机 + AWU 约 78ms 唤醒(RM0016 寄存器名) */
void low_power_init(void)
{
    /* 1. 主时钟:HSI 不分频;唤醒后直接用 HSI,省掉切换时间 */
    CLK_CKDIVR = 0x00;                  /* HSIDIV=0, CPUDIV=0 */
    CLK_ICKR  |= CLK_ICKR_FHWU;         /* 唤醒时 HSI 自动成为主时钟 */

    /* 2. 只留必要外设的时钟,其余门控关闭 */
    CLK_PCKENR1 = 0x00;                 /* 按实际需要再逐位打开 */

    /* 3. FLASH:活跃停机期间断电,换更低的休眠电流 */
    FLASH_CR1 &= (u8)~0x04;             /* AHALT = 0,唤醒时间增至微秒级 */

    /* 4. AWU:APRDIV = 39 -> APR 写 37(0x25),AWUTB=1001 */
    AWU_APR = 0x25;
    AWU_TBR = 0x09;
    AWU_CSR |= 0x10;                    /* AWUEN = 1 */

    /* 5. 唤醒后清标志,再继续业务 */
    while (AWU_CSR & 0x20) {            /* AWUF = 1 */
        AWU_CSR;                        /* 读该寄存器即清零 */
    }
}

void enter_active_halt(void)
{
    disableInterrupts();
    __halt();                           /* 对应 HALT 指令 */
    enableInterrupts();
}

六、六个反复出现的坑

现象根因处理
休眠电流远高于估算值调试器仍连着 SWIM;ADC、I2C 等外设时钟没关断开调试器再测;用 PCG 逐位关闭未用外设
执行 HALT 后必须按复位才醒把内部中断当成了唤醒源定时唤醒改用活跃停机 + AWU,停机只留外部中断
唤醒后第一帧串口数据乱码主时钟切换尚未完成就开始收发置 FHWU,或等 HSIRDY 后再初始化串口
定时周期比设计值短一成多LSI 偏差未实测,按 128kHz 标称值算的用 MSR 位配合 TIM3 输入捕捉测 LSI,再回填 APR
活跃停机电流降不下来AWUTB 仍是非零值,或 REGAH 未按需配置不用 AWU 时 AWUTB 清 0000;用 HSE 做 AWU 时钟时不要开 REGAH
写 APR 后定时器不动写成了复位值 3FhAPR 取值范围 00h ~ 3Eh,按 APRDIV − 2 换算

一句话总结:STM8S 的低功耗是一笔账——模式决定谁能醒你,时钟决定你跑多快,FLASH 掉电位决定你醒多快,AWU 分频决定你多久醒一次。四项一起算,休眠电流才等于设计值;只改其中一项,剩下的会替你把它拉回去。

本文基于 ST RM0016《STM8S 参考手册》中文第 4 版(参照 2009 年 1 月英文第 4 版)中的电源管理、时钟控制、FLASH 与自动唤醒章节整理优化。

需要定制开发?

沧州艾诺威电子 — 国家高新技术企业,20+项国家专利
嵌入式系统开发 · 物联网方案 · AI智能硬件 · 一站式交付

立即微信咨询

电话:13930711029 | 邮箱:tech@czinv.com | 24小时内响应