全部例程

电源控制(PWR)

W55MH32

更新于 2026年9月8日

本篇总结

使用 PWR,演示 PVD 可编程电压监测器,VDD 跨越阈值时通过 EXTI_Line16 中断打印告警。

🔑 KEIL MDK、UART调试、PWR、PVD

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

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

W55MH32 内置可编程电压监测器(PVD),允许用户通过 PLS[2:0] 位选择 8 级电压阈值(2.18V ~ 2.88V)。当 VDD 跨越设定的阈值时,通过 EXTI_Line16 产生中断,内核可在复位前做紧急处理(如保存数据、安全关闭外设)。本示例配置 PVD 阈值为 2.9V,通过串口打印欠压/恢复正常告警。

前置工具准备

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

硬件连接

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

引脚功能说明
PA9 / PA10USART1 TX/RX串口打印调试信息

工程结构

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

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

PVD 可编程电压监测器

POR/PDR 是固定阈值(约 1.92V/1.88V)自动复位,而 PVD 允许用户编程 8 级电压阈值。当 VDD 跨越设定阈值时,通过 EXTI_Line16 产生中断。

级别条件最小值典型值最大值单位
0上升沿/下降沿2.10 / 2.002.18 / 2.082.26 / 2.16V
1上升沿/下降沿2.19 / 2.092.28 / 2.182.37 / 2.27V
2上升沿/下降沿2.28 / 2.182.38 / 2.282.48 / 2.38V
3上升沿/下降沿2.38 / 2.282.48 / 2.382.58 / 2.48V
4上升沿/下降沿2.47 / 2.372.58 / 2.482.69 / 2.59V
5上升沿/下降沿2.57 / 2.472.68 / 2.582.79 / 2.69V
6上升沿/下降沿2.66 / 2.562.78 / 2.682.90 / 2.80V
7上升沿/下降沿2.76 / 2.662.88 / 2.783.00 / 2.90V

上升沿与下降沿

同一级别的上升沿阈值比下降沿高约 0.1V(迟滞),避免 VDD 在阈值附近抖动时频繁触发中断。通过 PWR_PVDLevelConfig(PWR_PVDLevel_2V9) 选择级别 7(典型 2.88V)。

步骤1:PVD 电压监测例程

配置 PVD 阈值 2.9V,VDD 跨越阈值时通过 EXTI_Line16 中断打印告警。

int main(void)
{
    RCC_ClocksTypeDef clocks;

    delay_init();
    UART_Configuration(115200);
    RCC_GetClocksFreq(&clocks);

    printf("\n");
    printf("SYSCLK: %3.1fMhz, HCLK: %3.1fMhz, PCLK1: %3.1fMhz, PCLK2: %3.1fMhz, ADCCLK: %3.1fMhz\n",
           (float)clocks.SYSCLK_Frequency / 1000000, (float)clocks.HCLK_Frequency / 1000000,
           (float)clocks.PCLK1_Frequency / 1000000, (float)clocks.PCLK2_Frequency / 1000000,
           (float)clocks.ADCCLK_Frequency / 1000000);

    printf("PWR PVD Test.\n");

    PVD_Configuration();
    while (1);
}

/* PVD 配置 */
void PVD_Configuration(void)
{
    EXTI_InitTypeDef EXTI_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);

    /* EXTI_Line16 = PVD,上升沿+下降沿触发 */
    EXTI_ClearITPendingBit(EXTI_Line16);
    EXTI_InitStructure.EXTI_Line    = EXTI_Line16;
    EXTI_InitStructure.EXTI_Mode    = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

    /* PVD 中断最高优先级 */
    NVIC_InitStructure.NVIC_IRQChannel                   = PVD_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    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 the selected PVD threshold\n");
        else
            printf("VDD Above the selected PVD threshold\n");

        EXTI_ClearITPendingBit(EXTI_Line16);
    }
}

轮询方式

若不想用中断,可在主循环中轮询:if (PWR_GetFlagStatus(PWR_FLAG_PVDO) == SET) printf("欠压");,每秒检查一次即可。

运行验证

打开 WIZ UartTool V1.0,波特率 115200。

PVD 例程:正常供电时无输出;缓慢调低 VDD 到 2.9V 以下时打印欠压告警,调回后打印恢复正常。

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

PWR PVD Test.

WIZ UartTool 串口输出 — PVD 欠压检测测试启动

VDD Below the selected PVD threshold

VDD Above the selected PVD threshold

WIZ UartTool 串口输出 — PVD 欠压/恢复正常告警

常见问题

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 配套开发板