全部例程

电源控制(PWR)

W55MH32

更新于 2026年9月8日

本篇总结

使用 PWR,实现 PVD 电压监测与睡眠/停止/待机三种低功耗模式。

🔑 KEIL MDK、UART调试、PWR

硬件平台:本例程基于 W55MH32L-EVB 开发板运行。

采购推荐:点击前往 WIZnet 官方淘宝店铺 选购 W55MH32L-EVB

W55MH32 的工作电压(VDD)为 2.0~3.6V,内置电压调节器提供 1.8V 内核电源。芯片集成完整的电源管理器:上电复位(POR)、掉电复位(PDR)和可编程电压监测器(PVD)。当 CPU 不需运行时,可利用睡眠、停止、待机三种低功耗模式节省功耗。本示例演示三种模式的进入与唤醒,并通过串口打印状态。

前置工具准备

开始本例程前,请确认以下工具已安装:

硬件连接

PWR 为片内外设。串口通过 USART1(PA9/PA10) 打印信息,待机模式用 PA0(WKUP) 唤醒。仅需一根 Micro USB 线连接 DEBUG USB 口。测试 PVD 时可用可调电源缓慢调低 VDD 观察告警。

引脚功能说明
PA9 / PA10USART1 TX/RX串口打印调试信息
PA0WKUP待机/停止模式唤醒引脚(上升沿)

工程结构

工程位于 SDK 内 1.SDK\ModuleDemo\PWR\,核心文件如下:

PWR/
├── USER/
│   ├── main.c            ← PWR 模式切换 + WKUP 唤醒 + PVD 监测主循环
│   ├── w55mh32_conf.h    ← 外设头文件集中包含
│   ├── w55mh32_it.c/h    ← 中断服务函数
│   ├── system_w55mh32.c/h← 系统初始化(时钟配置)
│   └── startup_w55mh32.s ← 启动文件
└── SYSTEM/
    └── delay/
        └── delay.c/h      ← SysTick 延时函数

电源架构与电源管理器

W55MH32 的电源系统分为几个部分:

  • VDD 主电源(2.0-3.6V):为芯片主体供电,内置调节器降压到 1.8V 供内核
  • VDDA/VSSA:ADC 独立供电,过滤 PCB 毛刺干扰,提高转换精度
  • VBAT 电池备份:VDD 掉电后为 RTC 和备份寄存器供电,VBAT 脚接电池或超级电容
  • 电压调节器:三模式——运转(正常1.8V)、停止(低功耗1.8V保SRAM)、待机(关闭,SRAM丢失)

POR/PDR:上电复位和掉电复位,VDD 低于阈值时自动复位,无需外部复位电路。
PVD:可编程电压监测器,用户设定阈值(PLS[2:0]),VDD 跨越阈值时通过 EXTI_Line16 触发中断,可用于紧急关机保护。

三种低功耗模式对比

模式进入方式唤醒源SRAM/寄存器功耗
睡眠WFI/WFE (SLEEPDEEP=0)任一中断/事件保留
停止SLEEPDEEP=1 + PDDS=0 + WFI任一外部中断保留
待机SLEEPDEEP=1 + PDDS=1 + WFIWKUP引脚/RTC闹钟/NRST/IWDG丢失(仅备份域保留)最低

选型建议

睡眠:唤醒最快,适合短暂等待中断;停止:保留寄存器,适合周期性唤醒;待机:功耗最低但SRAM丢失,唤醒等同复位,适合长时间深度休眠。

步骤1:待机模式 (PWR_Standby)

使能 WKUP 引脚(PA0),串口接收 's' 后配置所有 GPIO 为模拟输入降低功耗,进入待机模式。PA0 上升沿唤醒,唤醒后等同复位重启。

/* 使能 PWR 和 BKP 时钟 */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);

/* 使能 WKUP 引脚 PA0 */
PWR_WakeUpPinCmd(ENABLE);

printf("PWR Standby Test.\r\n");
printf("Please Input 's', Come Standby Mode\r\n");

/* 等待串口输入 's' */
while (GetCmd() != 's');

/* 所有 GPIO 设为模拟输入,降低功耗 */
GPIO_Configuration();

/* 清除 WUF 标志后进入待机模式 */
PWR_ClearFlag(PWR_FLAG_WU);
PWR_EnterSTANDBYMode();
/* 唤醒后等同复位,以下代码不会执行 */

如果你想自定义

  • RTC 闹钟唤醒 → 配置 RTC 闹钟事件,无需 WKUP 引脚即可定时唤醒
  • 清除 WUF 标志 → 进入前必须调用 PWR_ClearFlag(PWR_FLAG_WU),否则之前残留的唤醒标志会阻止进入待机

步骤2:停止模式 (PWR_Stop)

与待机类似,但停止模式保留 SRAM 和寄存器内容,唤醒后从断点继续执行。唤醒后系统时钟自动切到 HSI(8MHz),需重新配置时钟。

/* 配置 PA0 为外部中断上升沿触发 */
WAKEUP_Configuration();

/* 等待 's' 后进入停止模式 */
while (GetCmd() != 's');
GPIO_Configuration();

/* 低功耗调节器 + WFI 进入停止模式 */
PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);

/* 唤醒后从此处继续执行(非复位) */
/* 注意:唤醒后时钟自动切回 HSI 8MHz,需重配 */
SystemInit();               // 重新配置系统时钟
UART_Configuration(115200); // 重新初始化串口
printf("WakeUp Success\r\n");

步骤3:PVD 电压监测 (PWR_PVD)

配置 PVD 阈值(如 2.9V),VDD 跨越阈值时通过 EXTI_Line16 触发中断,在中断中判断是过压还是欠压。

/* PVD 配置 */
void PVD_Configuration(void)
{
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);

    /* EXTI_Line16 上升沿+下降沿触发 */
    EXTI_InitStructure.EXTI_Line    = EXTI_Line16;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
    EXTI_Init(&EXTI_InitStructure);

    /* PVD 中断最高优先级 */
    NVIC_InitStructure.NVIC_IRQChannel = PVD_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_Init(&NVIC_InitStructure);

    /* 阈值 2.9V 并使能 */
    PWR_PVDLevelConfig(PWR_PVDLevel_2V9);
    PWR_PVDCmd(ENABLE);
}

/* PVD 中断服务函数 */
void PVD_IRQHandler(void)
{
    if (EXTI_GetITStatus(EXTI_Line16) != RESET)
    {
        if (PWR_GetFlagStatus(PWR_FLAG_PVDO) == SET)
            printf("VDD Below PVD threshold!\r\n");   // 欠压
        else
            printf("VDD Above PVD threshold\r\n");     // 恢复正常
        EXTI_ClearITPendingBit(EXTI_Line16);
    }
}

如果你想自定义

  • 调整阈值 → 修改 PWR_PVDLevelConfig() 参数,可选 2.2V~2.9V 共 8 级
  • 紧急关机 → 在 PVD 中断中执行数据保存、外设安全关闭等操作后再进入待机

运行验证

打开 WIZ UartTool V1.0,波特率 115200。程序运行后打印时钟信息与提示。发送字符 's' 进入对应低功耗模式:

SYSCLK: 72.0Mhz, HCLK: 72.0Mhz, PCLK1: 36.0Mhz, PCLK2: 72.0Mhz

PWR Standby Test.

Enable WakeUp Pin - PA0

Please Input 's', Come Standby Mode

(发送 's' 后芯片进入待机,串口停止输出)

(按 PA0 按键唤醒,芯片复位重启,重新打印上述信息)

 

常见问题

Q: 进入待机模式后立即被唤醒

进入前未清除 WUF 唤醒标志。调用 PWR_ClearFlag(PWR_FLAG_WU) 清除残留标志后再进入。

Q: 停止模式唤醒后串口乱码

唤醒后系统时钟自动切换到 HSI(8MHz),而串口波特率基于原时钟配置。唤醒后需调用 SystemInit() 重新配置时钟,再重新初始化串口。

Q: 停止模式功耗没降下来

进入前未关闭 ADC/DAC 等外设(它们仍消耗电流)。设置 ADC_CR2.ADON=0DAC_CR.ENx=0 关闭。同时将所有未用 GPIO 设为模拟输入。

Q: PVD 中断频繁触发

VDD 在阈值附近抖动导致反复跨越。可在软件中加去抖延时,或调整阈值远离当前 VDD 实际值。

Q: 调试时进入低功耗后失去连接

低功耗模式下内核时钟停止导致调试断连。设置 DBGMCU_CR 寄存器中的对应位,可在低功耗模式下保持调试时钟。

总结

本文基于 W55MH32 实现了电源管理与三种低功耗模式:

  • 电源管理器:POR/PDR 自动复位无需外部电路,PVD 可编程监测 VDD 越限并中断告警
  • 三种低功耗:睡眠(CPU停,外设运行)→停止(全时钟停,SRAM保留)→待机(1.8V断电,SRAM丢失),功耗递减,唤醒时间递增
  • 唤醒方式:睡眠/停止由外部中断唤醒,待机由 WKUP 引脚/RTC 闹钟/NRST 唤醒,唤醒后待机等同复位
  • 降功耗技巧:进入前关闭 ADC/DAC、GPIO 设模拟输入、调节器选低功耗模式,可进一步降低电流

下载本章例程

我们提供完整的工程文件以及配套开发板,方便你随时测试,快速完成产品开发:

开发环境: Keil MDK5 配套开发板