本篇总结
使用 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,通过串口打印欠压/恢复正常告警。
前置工具准备
开始本例程前,请确认以下工具已安装:
- WIZ UartTool V1.0:串口调试工具:点击下载
硬件连接
PWR/PVD 为片内外设。串口通过 USART1(PA9/PA10) 打印信息。仅需一根 Micro USB 线连接 DEBUG USB 口。测试 PVD 时可用可调电源缓慢调低 VDD 观察告警输出。
| 引脚 | 功能 | 说明 |
| PA9 / PA10 | USART1 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.00 | 2.18 / 2.08 | 2.26 / 2.16 | V |
| 1 | 上升沿/下降沿 | 2.19 / 2.09 | 2.28 / 2.18 | 2.37 / 2.27 | V |
| 2 | 上升沿/下降沿 | 2.28 / 2.18 | 2.38 / 2.28 | 2.48 / 2.38 | V |
| 3 | 上升沿/下降沿 | 2.38 / 2.28 | 2.48 / 2.38 | 2.58 / 2.48 | V |
| 4 | 上升沿/下降沿 | 2.47 / 2.37 | 2.58 / 2.48 | 2.69 / 2.59 | V |
| 5 | 上升沿/下降沿 | 2.57 / 2.47 | 2.68 / 2.58 | 2.79 / 2.69 | V |
| 6 | 上升沿/下降沿 | 2.66 / 2.56 | 2.78 / 2.68 | 2.90 / 2.80 | V |
| 7 | 上升沿/下降沿 | 2.76 / 2.66 | 2.88 / 2.78 | 3.00 / 2.90 | V |
上升沿与下降沿
同一级别的上升沿阈值比下降沿高约 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=0 和 DAC_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 设模拟输入、调节器选低功耗模式,可进一步降低电流