
简介STM32L系列官方例程包是一套面向低功耗嵌入式开发的完整示例集合基于意法半导体官方标准外设库V1.3.1构建适配基于Cortex-M0或Cortex-M3内核的超低功耗MCU。例程覆盖模数转换、数模转换、外部中断、I2C总线通信、通用输入输出控制、串口收发等常用外设驱动并延伸至电池供电设备、传感器采集、调试终端等典型场景适合嵌入式工程师与学生快速上手。资源共1443个文件压缩包约24.25MB以C源码和头文件为主体辅以网页文档、示意图、文本说明及IDE工程文件目录结构清晰便于按模块查阅和直接编译。除基础外设外还提供基于STM32L152-EVAL评估板的LCD显示、SDIO存储卡、定时器、实时时钟、Flash访问等应用级例程帮助理解时钟树、中断优先级与低功耗模式的协同设计。已有2826人浏览学习整套例程遵循官方库组织规范既可作为项目基础模板也可作为驱动开发和调试排错参考。1. 为什么大家都在找STM32L例程STM32L从名字就能看出来L不是白叫的Low power。它把超低功耗这一块做到了一个很舒服的位置和STM32F系列最大的区别不是性能而是整个系统的功耗设计哲学从内核、时钟、外设到电源管理每一层都在为“省电”服务。你搜索STM32L例程搜到的基本都是嵌入式开发者在做电池供电设备、传感器节点、智能仪表、可穿戴设备时整理出来的工程模板目标很明确把一个能跑、能睡、能唤醒的外设工程快速搭起来。找这类例程的大概有三类人。一类是从STM32F103这类经典片子切过来的F103的寄存器、标准外设库他们很熟但换到L系列后发现HAL库、LL库、低功耗外设全都不一样需要一份例程做对照。第二类是直接做产品的比如水表、气表、定位器、温湿度记录仪他们不想从零看手册就想拿一个现成工程把传感器、无线模块接上然后把整机电流调到微安级。还有一类是学习型用户手里有NUCLEO-L476RG或者STM32L072 Discovery板想理解LPTIM、LPUART、RTC唤醒这些新东西到底怎么用。这三类人目标不同但最后都会落到同一个问题上一套写得清楚、能直接跑的STM32L例程到底包含哪些东西这篇文章就把这个问题讲透。我在嵌入式一线干了十几年早期做STM32F系列后来转向低功耗产品开发STM32L系列成了我最常用的平台。下面这些内容不是手册翻译而是我从实际项目中提炼出来的经验。准备从环境搭建、例程结构、低功耗核心、调试避坑等几个维度把一套有参考价值的STM32L例程该有的样子完整拆给你看。2. 环境搭建CubeMX、HAL库还是LL库2.1 开发环境怎么搭最省心我用过的组合里最推荐的是STM32CubeMX生成工程再配Keil MDK或者STM32CubeIDE编译调试。STM32CubeMX选芯片型号时直接输入STM32L4、STM32L0或者STM32L1列表会筛出对应型号。关键一步是在Project Manager里选Toolchain/IDE常用的是MDK-ARM或STM32CubeIDE。如果你用的是CubeIDECubeMX生成的.ioc文件可以直接打开不需要再手工移植。关于库的选择这里必须多说两句。STM32L系列有HAL库和LL库两套API很多人一上来就选HAL其实不然。HAL库的特点是抽象层次高外设初始化、数据收发都有完整封装但封装也带来了额外的函数调用开销和锁机制对低功耗场景不友好。LL库在寄存器和HAL之间做了一层轻薄封装很多外设操作可以做到时钟级精确控制特别适合PWR、LPTIM、RTC这种低功耗外设。我的做法是外层逻辑用HAL低功耗模式切换和唤醒配置用LL两者可以混用。CubeMX里其实每个外设都可以单独勾选Use LL或者Use HAL不用全项目统一这点很多人不知道。2.2 官方例程包的结构和定位技巧ST官方把例程包叫STM32Cube_FW_L4或L0、L1在STM32CubeMX安装目录的Repository文件夹下可以找到比如STM32Cube\Repository\STM32Cube_FW_L4_V1.17.0。打开之后主要看Project、Drivers、Middlewares三个目录。最值得看的是Projects下的板级例程命名规则很清晰比如Projects\NUCLEO-L476RG\Examples\PWR\PWR_STOP2。每个例程文件夹里有Core、App、EWARMIAR、MDK-ARM、STM32CubeIDE几个子目录。想直接在Keil里跑就进MDK-ARM双击开发工程。想用命令行看代码Core和App下的源码就是全部主体。定位技巧如果你要的是低功耗相关优先看Examples\PWR要串口就看Examples\UART或Examples\LPUART要做I2C传感器读取看Examples\I2C。官方例程虽然写得偏验证板但代码风格统一注释也算到位关键是PWR例程里把Stop模式、Standby模式、不同唤醒源的配置都演示了这比任何第三方教程都靠谱。我第一次调Stop2模式就是直接拿官方PWR_STOP2例程改出来的省了至少一天查手册的时间。3. 一套STM32L例程的核心内容拆解3.1 GPIO和时钟所有例程的地基不管是什么L系列例程GPIO部分都是第一步。STM32L和F系列一样GPIO有输入、输出、复用、模拟四种模式但低功耗设计里有几个F系列不太强调的细节一是未使用的引脚在进入低功耗前要设置为模拟模式因为数字输入模式会产生漏电流悬空引脚更是容易造成额外功耗二是输出引脚的速度等级不要盲目设High高速率意味着更大的翻转电流和EMI外部设备不要求高速的话用Low或Medium就足够。时钟部分官方例程一般默认用MSIMulti-speed internal oscillator作为系统时钟因为MSI可以做到低功耗和高精度的平衡而且可以自动根据电压调节频率。STM32L4的MSI最大可以到48MHz甚至更高但实际例程很多时候只跑4MHz或者8MHz因为很多低功耗应用根本不需要高主频频率越高功耗越大这是最简单的功耗公式P C × V² × f。在例程里改时钟我习惯用CubeMX里的Clock Configuration页面去可视化调整直接看HCLK、PCLK1、PCLK2等总线频率的变化避免手工配置时把总线时钟配超了。3.2 低功耗三档Sleep、Stop、Standby低功耗是STM32L例程的重头戏。绝大多数例程都会把三个睡眠档位讲清楚Sleep模式最简单CPU停止外设还在跑中断随时可以唤醒。适合那些有数据正在传输、暂时等一等的场景。Stop模式STM32L4里细分为Stop0/1/2L0/L1也有类似Stop模式会把大部分时钟停掉SRAM保持唤醒后可以从断点继续执行典型功耗在微安级别。Standby模式就彻底了除了RTC、备份寄存器和几个唤醒引脚其他全断电功耗可以到纳安级代价是唤醒后整个程序相当于重新启动。我之前做过一个电池供电的温湿度记录仪就是用Stop2模式做周期唤醒RTC每隔5分钟触发一次中断唤醒后读温湿度传感器存到Flash里然后重新进Stop2。实测整机平均电流还不到3微安三节AAA电池撑了大半年。这个工程的核心就是模仿官方PWR_STOP2例程里的进入流程先把串口关掉再把ADC关掉配置唤醒源设置低功耗稳压器模式最后执行WFI或WFE。注意WFE其实在某些场景下比WFI更合适比如需要事件唤醒时两者区别在ARM文档里有专门说明但例程里常见用法是WFI原因是它最简单直观。进入Stop前一定要把外设时钟关掉用__HAL_RCC_xxx_CLK_DISABLE()逐个关闭否则外设虽然没运行但它的时钟还在会不断产生噪声和漏电。很多初学者写的低功耗例程电流测下来不理想问题大多出在这里。下表是我常用的三种睡眠模式对比整理例程时可以直接参考模式CPU状态外设时钟SRAM常用唤醒源实测电流参考Sleep停止保持保留任意中断毫安级别Stop2停止大部分关闭保留RTC/LPTIM/EXTI/LPUART微安级别Standby停止全部关闭丢失RTC/唤醒引脚/复位纳安级别3.3 串口、I2C、ADC的例程细节串口在低功耗场景里常常换成LPUARTLow Power UART它可以在Stop模式下继续监听外部数据不需要CPU全程介入用起来和普通UART类似但引脚要连到特定的低功耗引脚上。很多例程会在系统手册里标注哪些引脚支持LPUART功能比如L4系列的PA0、PA1之类的复用引脚。如果只是做调试打印我建议进入Stop前把UART关掉等唤醒后再开否则串口模块在睡眠状态下的空闲中断很容易把系统不小心拉起来。I2C例程注意点在于STM32L系列很多信号还是开漏输出需要外部上拉或者内部上拉。官方例程一般会在I2C初始化里把内部上拉打开但如果你外接传感器板上已经有上拉电阻内部上拉和外部上拉并联之后可能导致总上拉太强I2C上升沿变慢通讯出错。所以拿到别人移植好的I2C例程先检查上拉配置。ADC部分STM32L系列支持硬件过采样和多种采样时间调节。低功耗例程里用ADC一般不会让ADC持续采样而是等唤醒后一次性触发采样采完马上关掉。这部分例程我最常用的写法是HAL_ADC_Start_DMA读一个DMA buffer数据到了之后在中断里立刻HAL_ADC_Stop_DMA避免DMA一直在跑把功耗带上去。4. 移植和调试中的常见坑与实测经验4.1 低功耗模式下调试器掉线这是几乎所有第一次搞STM32L低功耗的人都会遇到的问题仿真器在程序进入Stop或者Standby之后IDE的调试连接会断掉断点再也打不中甚至Keil报Cannot access target。原因很简单调试接口本身也是外设功耗一降内核时钟停了SWD调试模块也就没法工作。解决方法有两个。一是临时屏蔽掉进入低功耗的代码先跑通功能最后再把低功耗打开。这是最稳妥的流程别一上来就全开低功耗然后想在上电那一刻打断点。二是用DBGMCU配置寄存器比如在调试期间把DBG_STOP位、DBG_STANDBY位打开这样CPU进入低功耗模式后调试器能检测到连接强行保持内核时钟不会完全掉线。但是要注意这个寄存器是调试专用的设备量产后如果还留着会让功耗升高所以量产固件里必须把这个配置去掉或做好条件编译。4.2 唤醒源优先级和看门狗打架低功耗例程里唤醒源一般有RTC闹钟、LPTIM超时、LPUART接收、外部中断引脚等。多个唤醒源同时开的时候一定要在唤醒中断处理里做出优先级判断。我在实际项目里遇到过一个问题设备在低功耗模式下应该靠外部中断唤醒但每次按键唤醒后看门狗立刻把系统复位了。折腾了很久才发现代码在进入Stop前没有把独立看门狗暂停而看门狗在Stop模式下还在计数一旦超时系统只能复位。解决办法是在进Stop前及时喂狗或者根据需求开RTC去周期性地喂狗再彻底进入低功耗模式。LPTIM也可以作为一个低功耗喂狗定时器在Stop模式下定时唤醒系统去喂狗然后继续睡这样既保证看门狗的监控功能又不会让复位打断正常工作流程。4.3 电流测量时被板载器件坑如果用的是NUCLEO或Discovery板测低功耗电流时板上那颗ST-LINK的功耗是跑不掉的。以NUCLEO为例ST-LINK部分和MCU部分共用一个供电连接哪怕仿真器没用来在线调试只要供电在ST-LINK芯片就要吃掉几个毫安你还想测微安电流完全测不出来。解决办法是看板子原理图找到把ST-LINK和MCU供电隔开的那颗跳线帽或0欧电阻NUCLEO板上一般是一个黄色跳线标签是SB或IDD相关。我用NUCLEO-L476RG测低功耗时会直接把跳线拔掉然后用外部3.3V电源从MCU的VDD引脚单独供电并把电流表串进电源回路里。这时候测到的才是MCU本身的真实功耗。没有跳线帽的板子用刻刀切断PCB走线也行但那种方法太伤板子不推荐。4.4 引脚浮空与GPIO速率对功耗的影响很多例程跑在正常模式时一切正常一进低功耗电流就是比手册多出几十微安。排查方向除了时钟和外设九成问题出在GPIO上。未使用的GPIO如果没有配置成模拟模式它们会处于数字输入状态引脚悬空时电平不确定输入缓冲器里的CMOS反相器会在大约中间电压附近来回翻转每根引脚都可能多出微安级的漏电。几十个引脚加起来电流就上去了。另一种情况是GPIO输出高电平时外设模块处于空闲状态但引脚上的外部电阻还在消耗电流。例如你用GPIO去控制LED输出高电平时LED点亮虽然逻辑没问题但进低功耗前不清掉这个状态LED就一直亮着电流一下子多了好几毫安。所以在进入低功耗前要遍历一遍所有GPIO把控制外设电源的引脚保持低电平把悬空的引脚配成模拟输入这个习惯要内化成肌肉记忆。为了快速排查引脚问题我整理了一个检查表在调试低功耗例程时逐条对照检查项操作预期效果未使用引脚配置为模拟模式消除输入缓冲器漏电使用中引脚确认为明确电平避免悬空翻转LED/指示引脚进入低功耗前拉低避免外部电阻耗流外设时钟逐个关闭不需要的外设减少内部时钟活动调试口量产版本关闭DBGMCU配置降低量产后功耗5. 我的实战建议一个电池设备的低功耗例程怎么落地5.1 参考路径与最小改动方案如果你要开发一个基于STM32L系列的电池供电产品我的建议是不要从零写也不要大改特改。最佳路径是先找同型号官方板子的PWR例程比如STM32Cube_FW_L4下NUCLEO-L476RG的PWR_STOP2例程然后在此基础上只改三处第一把系统时钟频率改成你产品所需的最低频率第二把唤醒源从官方的按键外部中断改成你产品实际的RTC闹钟或者LPTIM定时器第三把你产品的外设初始化代码加进去但同时补上进入低功耗前关闭这些外设的代码。这样整个低功耗核心逻辑是官方验证过的你只需要处理自己产品的外设部分调试难度降低一个量级。我之前做过一个烟雾报警器的低功耗改造项目就是在官方PWR_STOP2例程基础上加了一个SGP30温湿度传感器和一个NB-IoT模组。SGP30用I2C读NB-IoT用UART通信两套外设在正常情况下跑进Stop前把两个外设的时钟关掉GPIO配成浮空输入或固定在低电平然后靠RTC每天固定时间唤醒采集数据、上传云端再继续睡。整机平均电流实测控制在10微安以内完全满足烟感国标对电池寿命的要求。5.2 实测数据与避坑补充我这里放一个最近实测的NUCLEO-L476RG裸板数据给各位一个参考范围运行态跑4MHz MSI时MCU电流大概在1.3mA左右进Stop2模式所有外设关闭、SRAM保持电流在1.2uA左右如果启用LPTIM作为定时唤醒源额外增加0.3uA左右。到了Standby模式电流能压到0.1uA以下但唤醒就要走完整复位流程。这些数值跟手册数据差别不大关键是要排除板载ST-LINK和LED的消耗。最后分享一个很多人都会踩的坑调试阶段用串口打印数据忙起来就忘了在进低功耗之前把串口关掉结果设备看起来进入睡眠了实际串口空闲中断把系统一次次唤醒或者功耗莫名其妙高了几百微安。我的习惯是在低功耗入口函数里用条件编译包一段“关闭所有调试外设”的代码调试开启时走打印路径量产版本直接走低功耗路径两边互不干扰。这样既保留调试能力也不用担心产品上线后功耗翻车。如果你也在折腾STM32L的低功耗不妨按这个思路去整理自己的例程先跑通官方PWR例程再逐步加外设最后再处理细节坑。你会发现低功耗开发并不是玄学只要把每一层功耗来源都搞清楚数据完全在可控范围内。本文还有配套的精品资源点击获取