5.21 PWR 使用说明

本章说明 N32H49x 标准外设库中 PWR 驱动的文件组成与 30 个公开函数,以及 PVD、SLEEP、STOP、STANDBY 四个示例。电源管理单元负责电压监测、唤醒源使能与低功耗模式切换;进入 SLEEP、STOP、STANDBY 的条件、唤醒后时钟状态与备份域访问规则请配合用户手册的“电源管理(PWR)”章节阅读。

5.21.1 相关文件

相对路径 作用
firmware/n32h49x_std_periph_driver/inc/n32h49x_pwr.h 定义 PVD 阈值、唤醒引脚、标志位等取值,声明 30 个公开函数
firmware/n32h49x_std_periph_driver/src/n32h49x_pwr.c 实现上述 30 个函数:电压检测、唤醒配置、低功耗模式进入、标志与复位、备份域控制
projects/n32h49x_EVAL/examples/PWR/ PWR 示例根目录,含 PVD、SLEEP、STOP、STANDBY 4 个示例
projects/n32h49x_EVAL/examples/PWR/PVD/ 该示例的工程目录组成:MDK-ARM/、EWARM/、inc/、src/、readme.txt
projects/n32h49x_EVAL/bsp/ 该示例引用的公共板级文件:串口日志与延时函数

5.21.2 API 参考

搜索 API共 30 个函数

以下 30 个公开函数按 n32h49x_pwr.h 的声明顺序分为 8 组;每个条目给出功能摘要与 n32h49x_pwr.c 中该函数正上方的注释原文。

基础与备份域

PWR_DeInit、PWR_BackupAccessEnable

PVD 电压监测

PWR_PvdEnable、PWR_PVDLevelConfig、PWR_PVDSourceConfig、PWR_PVDINPinSelect

唤醒引脚与外设

PWR_WakeUpPinEnable、PWR_WakeUpPinPolarity、PWR_WakeUpPeriphEnable

低功耗模式

PWR_EnterSLEEPMode、PWR_EnterSTOPMode、PWR_EnterSTANDBYMode

标志与复位

PWR_GetFlagStatus、PWR_ClearFlag、PWR_EnableIWDGReset

BKR 与备份 SRAM

PWR_ConfigBKROutput、PWR_EnableBKPSRAMRetainInStandbyMode、PWR_EnableBKPSRAMRetainInVbatMode

LSE 时钟安全系统

PWR_EnableLSENoiseMitigation、PWR_EnableLSECSSCrystalInt、PWR_ConfigLSECSSBypassHighLimit、PWR_EnableLSECSSRTCsourceSwitch、PWR_GetLSECSSFlagStatus、PWR_ClearLSECSSFlag

LCO 与 NRST

PWR_ConfigLco、PWR_EnableLCO、PWR_EnableNRSTOut、PWR_ConfigNRSTDigitalFilterWidth、PWR_EnableNRSTDigitalFilter、PWR_EnableNRSTAnalogFilter

void PWR_DeInit(void)将 PWR 外设寄存器恢复为默认复位值。
源码注释
name    PWR_DeInit.
fun     Deinitializes the PWR peripheral registers to their default reset values.
param   none
return  none
void PWR_BackupAccessEnable(FunctionalState Cmd)使能或禁止对 RTC 与备份寄存器的访问。
源码注释
name  PWR_BackupAccessEnable.
fun   Enables or disables access to the RTC and backup registers.
param   Cmd:
          - ENABLE
          - DISABLE
return  none
void PWR_PvdEnable(FunctionalState Cmd)使能或禁止电源电压检测器(PVD)。
源码注释
name    PWR_PvdEnable.
fun     Enables or disables the Power Voltage Detector(PVD).
param   Cmd:
          - ENABLE
          - DISABLE
return  none
void PWR_PVDLevelConfig(uint32_t level)配置电源电压检测器(PVD)的电压阈值。
源码注释
name    PWR_PVDLevelConfig.
fun     Configures the voltage threshold detected by the Power Voltage Detector(PVD).
param   level (The input parameters must be the following values):
          - PWR_PVD_LEVEL_2V18    PVD level is 2.18V
          - PWR_PVD_LEVEL_2V28    PVD level is 2.28V
          - PWR_PVD_LEVEL_2V38    PVD level is 2.38V
          - PWR_PVD_LEVEL_2V48    PVD level is 2.48V
          - PWR_PVD_LEVEL_2V58    PVD level is 2.58V
          - PWR_PVD_LEVEL_2V68    PVD level is 2.68V
          - PWR_PVD_LEVEL_2V78    PVD level is 2.78V
          - PWR_PVD_LEVEL_2V88    PVD level is 2.88V

          - PWR_PVD_LEVEL_1V78    PVD level is 1.78V
          - PWR_PVD_LEVEL_1V88    PVD level is 1.88V
          - PWR_PVD_LEVEL_1V98    PVD level is 1.98V
          - PWR_PVD_LEVEL_2V08    PVD level is 2.08V
          - PWR_PVD_LEVEL_3V28    PVD level is 3.28V
          - PWR_PVD_LEVEL_3V38    PVD level is 3.38V
          - PWR_PVD_LEVEL_3V48    PVD level is 3.48V
          - PWR_PVD_LEVEL_3V58    PVD level is 3.58V
return  none
void PWR_PVDSourceConfig(uint32_t PVD_source)选择 PVD 的检测来源。
源码注释
name    PWR_PVDSourceConfig.
fun     PVD Source selection.
param   PVD_source (The input parameters must be the following values):
          - PWR_PVD_VDD
          - PWR_PVD_PVDIN
return  none
note    none
void PWR_PVDINPinSelect(PVD_IN_SEL PVD_pin)选择 PVD_IN 引脚。
源码注释
name    PWR_PVDINPinSelect.
fun     PVD_IN pin selection.
param   PVD_pin (The input parameters must be the following values):
          - PVD_IN_PA10
          - PVD_IN_PB7
return  none
note    none
void PWR_WakeUpPinEnable(uint32_t pin, FunctionalState Cmd)使能唤醒引脚功能。
源码注释
name    PWR_WakeUpPinEnable.
fun     Enables the Wakeup Pin functionality.
param   pin (The input parameters must be the following values):
          - WAKEUP_PIN0EN   WKUP0(PE6)
          - WAKEUP_PIN1EN   WKUP1(PA0)
          - WAKEUP_PIN2EN   WKUP2(PC13)
          - WAKEUP_PIN3EN   WKUP3(PA2)
          - WAKEUP_PIN4EN   WKUP4(PC5)
          - WAKEUP_PIN5EN   WKUP5(PD2)
          - WAKEUP_PIN6EN   WKUP6(PD3)
param   Cmd:
          - ENABLE
          - DISABLE
return  none
void PWR_WakeUpPinPolarity(uint32_t pin, WAKEUP_PIN_POL polarity)设置唤醒引脚的极性。
源码注释
name    PWR_WakeUpPinPolarity.
fun     Enables the Wakeup Pin polarity.
param   pin (The input parameters must be the following values):
          - WAKEUP_PIN0POL   WKUP0(PE6)
          - WAKEUP_PIN1POL   WKUP1(PA0)
          - WAKEUP_PIN2POL   WKUP2(PC13)
          - WAKEUP_PIN3POL   WKUP3(PA2)
          - WAKEUP_PIN4POL   WKUP4(PC5)
          - WAKEUP_PIN5POL   WKUP5(PD2)
          - WAKEUP_PIN6POL   WKUP6(PD3)
param   polarity (The input parameters must be the following values):
          - POL_LOW
          - POL_HIGH
return  none
void PWR_WakeUpPeriphEnable(uint32_t periph, FunctionalState Cmd)使能唤醒外设功能。
源码注释
name    PWR_WakeUpPeriphEnable.
fun     Enables the Wakeup periph functionality.
param   periph (The input parameters must be the following values):
          - WAKEUP_PERIPH0EN   PERIPH0(LPTIM1 and LPTIM2)
          - WAKEUP_PERIPH1EN   PERIPH1(RTC and LSECSS)
param   Cmd:
          - ENABLE
          - DISABLE
return  none
void PWR_EnterSLEEPMode(PWR_SLEEPONEXIT_STATUS SLEEPONEXIT, uint8_t PWR_SLEEPEntry)进入 SLEEP 模式。
源码注释
name    PWR_EnterSLEEPMode.
fun     Enters SLEEP mode.
param   status (The input parameters must be the following values):
          - PWR_SLEEP_ON_EXIT
          - PWR_SLEEP_NOW
param   enter_mode (The input parameters must be the following values):
          - PWR_SLEEPENTRY_WFI    enter SLEEP mode with WFI instruction
          - PWR_SLEEPENTRY_WFE    enter SLEEP mode with WFE instruction
return  none
void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry)进入 STOP 模式。
源码注释
name    PWR_EnterSTOPMode.
fun     Enters STOP mode.
param   PWR_Regulator (The input parameters must be the following values):
          - PWR_REGULATOR_NORMAL      STOP mode with regulator in normal mode
          - PWR_REGULATOR_LOWPOWER    STOP mode with regulator in low power mode
param   PWR_STOPEntry (The input parameters must be the following values):
          - PWR_STOPENTRY_WFI    enter STOP mode with WFI instruction
          - PWR_STOPENTRY_WFE    enter STOP mode with WFE instruction
return  none
void PWR_EnterSTANDBYMode(void)进入 STANDBY 模式。
源码注释
name    PWR_EnterSTANDBYMode.
fun     Enters STANDBY mode.
param   none
return  none
FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG)检查指定的 PWR 标志是否置位。
源码注释
name   PWR_GetFlagStatus.
fun    Checks whether the specified PWR flag is set or not.
param PWR_FLAG (specifies the flag to check):
      This parameter can be one of the following values:
       - PWR_FLAG_WKUP0     PE6 Wake Up flag
       - PWR_FLAG_WKUP1     PA0 Wake Up flag
       - PWR_FLAG_WKUP2     PC13 Wake Up flag
       - PWR_FLAG_WKUP3     PA2 Wake Up flag
       - PWR_FLAG_WKUP4     PC5 Wake Up flag
       - PWR_FLAG_WKUP5     PD2 Wake Up flag
       - PWR_FLAG_WKUP6     PD3 Wake Up flag
       - PWR_FLAG_WKUPP     RTC or LSECSS or LPTIM1  or LPTIM2 Wake Up flag
       - PWR_FLAG_STANDBY   StandBy mode flag
       - PWR_FLAG_PVDRDF    PVD ready flag
       - PWR_FLAG_PVDOUT    PVD Output
       - PWR_FLAG_VBAT      VBAT mode flag
return The new state of PWR_FLAG
       - SET
       - RESET
void PWR_ClearFlag(uint32_t PWR_FLAG)清除 PWR 的挂起标志。
源码注释
name   PWR_ClearFlag.
fun    Clears the PWR's pending flags.
param  PWR_FLAG (specifies the flag to clear):
       This parameter can be one of the following values:
       - PWR_CLR_WKUP0     PE6 Wake Up flag
       - PWR_CLR_WKUP1     PA0 Wake Up flag
       - PWR_CLR_WKUP2     PC13 Wake Up flag
       - PWR_CLR_WKUP3     PA2 Wake Up flag
       - PWR_CLR_WKUP4     PC5 Wake Up flag
       - PWR_CLR_WKUP5     PD2 Wake Up flag
       - PWR_CLR_WKUP6     PD3 Wake Up flag
       - PWR_CLR_WKUPP     RTC or LSECSS or LPTIM1  or LPTIM2 Wake Up flag
       - PWR_CLR_STANDBY   StandBy mode flag
       - PWR_CLR_VBAT      VBAT mode flag
return  none
void PWR_ConfigBKROutput(uint32_t voltage_output)选择 BKR 稳压器的输出电压档位。
源码注释
name    PWR_ConfigBKROutput.
fun     Selects the BKR regulator output level.
param   voltage_output (The input parameters must be the following values):
          - PWR_BKR_OUTPUT_0_8V    output 0.8V
          - PWR_BKR_OUTPUT_0_9V    output 0.9V
return  none
note    none
void PWR_EnableIWDGReset(FunctionalState Cmd)配置 IWDG 计数到 0 时是否产生复位请求。
源码注释
name    PWR_EnableIWDGReset.
fun     Configure whether to generate a reset request when the IWDG counter reaches 0.
param   Cmd:
          - ENABLE
          - DISABLE
return  none.
void PWR_EnableBKPSRAMRetainInStandbyMode(FunctionalState Cmd)使能或禁止 STANDBY 模式下保留备份 SRAM。
源码注释
name    PWR_EnableBKPSRAMRetainInStandbyMode.
fun     Enable or disable BKP SRAM retain in standby mode.
param   Cmd:
          - ENABLE
          - DISABLE
return  none.
void PWR_EnableBKPSRAMRetainInVbatMode(FunctionalState Cmd)使能或禁止 VBAT 模式下保留备份 SRAM。
源码注释
name    PWR_EnableBKPSRAMRetainInVbatMode.
fun     Enable or disable BKP SRAM retain in Vbat mode.
param   Cmd:
          - ENABLE
          - DISABLE
return  none.
void PWR_EnableLSENoiseMitigation(FunctionalState Cmd)使能或禁止 LSE 噪声抑制。
源码注释
name    PWR_EnableLSENoiseMitigation.
fun     Enable or disable LSE noise mitigation.
param   Cmd:
          - ENABLE
          - DISABLE
return  none
note    Noise mitigation must be enabled after the RCC_BDCTRL.LSERD set.
void PWR_EnableLSECSSCrystalInt(FunctionalState Cmd)使能或禁止晶振模式下的 LSE 时钟安全系统中断。
源码注释
name    PWR_EnableLSECSSCrystalInt.
fun     Enable or disable LSE Clock Safety System Interrupt in Crystal Mode.
param   Cmd:
          - ENABLE
          - DISABLE
return  none
note    none
void PWR_ConfigLSECSSBypassHighLimit(uint32_t high_limit)配置旁路模式下 LSE 频率上限。
源码注释
name    PWR_ConfigLSECSSBypassHighLimit.
fun     Configuring the LSE Frequency High Limit for Bypass Mode.
param   high_limit (The input parameters must be the following values):
          - PWR_HIGH_LIMIT_1M
          - PWR_HIGH_LIMIT_160K
return  none
note    none
void PWR_EnableLSECSSRTCsourceSwitch(FunctionalState Cmd)使能或禁止 LSE 时钟失效时把 RTC 时钟源从 LSE 切换到 LSI。
源码注释
name    PWR_EnableLSECSSRTCsourceSwitch.
fun     Enable or disable switching the RTC clock source
        from LSE to LSI when the LSE clock fails.
param   Cmd:
          - ENABLE
          - DISABLE
return  none
FlagStatus PWR_GetLSECSSFlagStatus(uint32_t PWR_FLAG)检查指定的 PWR LSECSS 标志是否置位。
源码注释
name   PWR_GetLSECSSFlagStatus.
fun    Checks whether the specified PWR LSECSS flag is set or not.
param PWR_FLAG (specifies the flag to check):
      This parameter can be one of the following values:
       - PWR_FLAG_LSECSSCRYF    LSE Clock Security System Failure in Crystal Mode
       - PWR_FLAG_LSEFHF        LSE Frequency Exceeds High Limit Flag
       - PWR_FLAG_LSEFLF        LSE frequency below low limit flag
       - PWR_FLAG_LSECSSF       LSE Clock Security System Failure flag
return The new state of PWR_FLAG
       - SET
       - RESET
void PWR_ClearLSECSSFlag(void)清除 LSECSS 的全部标志。
源码注释
name    PWR_ClearLSECSSFlag.
fun     Clears the LSECSS all flags.
param   none
return  none
note  Clear the following flags:
       - PWR_FLAG_LSECSSCRYF    LSE Clock Security System Failure in Crystal Mode
       - PWR_FLAG_LSEFHF        LSE Frequency Exceeds High Limit Flag
       - PWR_FLAG_LSEFLF        LSE frequency below low limit flag
       - PWR_FLAG_LSECSSF       LSE Clock Security System Failure flag
void PWR_ConfigLco(uint32_t LCO_source)选择 LCO 低速时钟输出。
源码注释
name    PWR_ConfigLco.
fun     LCO low-speed clock output selection.
param   LCO_source (The input parameters must be the following values):
          - PWR_LCO_LSI
          - PWR_LCO_LSE
return  none
note    none
void PWR_EnableLCO(FunctionalState Cmd)使能或禁止低速时钟输出。
源码注释
name    PWR_EnableLCO.
fun     Enable or disable low-speed clock output
param   Cmd:
          - ENABLE
          - DISABLE
return  none
void PWR_EnableNRSTOut(FunctionalState Cmd)使能或禁止 NRST 引脚的输出功能。
源码注释
name   PWR_EnableNRSTOut.
fun    Enable or disable the output function of NRST Pin.
param   Cmd:
          - ENABLE
          - DISABLE
return  none.
void PWR_ConfigNRSTDigitalFilterWidth(uint32_t NRST_dfw)配置 NRST 数字滤波宽度。
源码注释
name   PWR_ConfigNRSTDigitalFilterWidth.
fun    Configuring the NRST digital filter width.
param  NRST_dfw:
        - 0x0 ~ 0xFF
return  none.
note  digital filter width =  sysclk * NRST_dfw.
void PWR_EnableNRSTDigitalFilter(FunctionalState Cmd)使能或禁止 NRST 数字滤波器。
源码注释
name    PWR_EnableNRSTDigitalFilter.
fun     Enable or disable NRST digital filter
param   Cmd:
          - ENABLE
          - DISABLE
return  none
void PWR_EnableNRSTAnalogFilter(FunctionalState Cmd)使能或禁止 NRST 模拟滤波器。
源码注释
name    PWR_EnableNRSTAnalogFilter.
fun     Enable or disable NRST Analog filter
param   Cmd:
          - ENABLE
          - DISABLE
return  none

5.21.3 Demo 示例说明

本节说明 PWR 的四个示例:PVD 通过电压检测产生中断,SLEEP、STOP、STANDBY 演示低功耗模式的进入与唤醒。

5.21.3.1 PVD 电压监测

工程目录: projects/n32h49x_EVAL/examples/PWR/PVD/

使能电源管理时钟→配置电压检测的外部中断线→设置检测阈值并使能检测→电压越限时触发中断并打印

项目 源码解读
功能 通过电源电压检测器监测供电电压;
电压越过 2.58V 阈值时在上升沿或下降沿触发中断,并在中断中打印提示信息
源码组成 src/main.c:main、EXTI_Configuration、NVIC_Configuration;
src/n32h49x_it.c:PVD_IRQHandler;
inc/main.h、inc/n32h49x_it.h:头文件;
readme.txt:功能、环境与使用说明;
MDK-ARM/、EWARM/:Keil 与 IAR 工程
关键配置 时钟:系统时钟 240MHz;
中断:PVD 输出接到 EXTI 第 16 线,上升沿与下降沿均触发,使能 PVD 中断并配置优先级;
检测:阈值设为 2.58V
程序与数据路径 main 先使能 PWR 与 BKP 时钟,再依次配置外部中断线与 NVIC;
随后设置 PVD 阈值并使能 PVD,等待 PWR_FLAG_PVDRDF 就绪;
电压越限时 PVD_IRQHandler 打印信息并清除中断标志
主要 API PWR_PVDLevelConfig、PWR_PvdEnable、PWR_GetFlagStatus
验证方法 编译烧录后串口打印“This is a PVD demo”与“PVD is enabled!”;
把电压调到 2.58V 附近,程序进入 PVD_IRQHandler 并打印“Enter PVD interrupt”
使用提示 硬件平台为全功能板 N32H497ZGL7_EVB V1.0;
开发环境为 KEIL MDK-ARM 5.34 或 IAR EWARM 8.50.1;
打印串口为 USART1(TX PA9,RX PA10,115200);
PVD 在电压跨越阈值时触发中断,需外部提供可调模拟电压
核心代码解读与移植

示例先使能 PWR 与 BKP 时钟,再配置 PVD 输出的外部中断线与中断向量,随后设置检测阈值并使能 PVD,最后等待电压越限触发中断。

数据路径: main 使能 PWR 与 BKP 时钟 → EXTI_Configuration 配置 EXTI 第 16 线 → NVIC_Configuration 使能 PVD 中断 → main 设置阈值并使能 PVD → 电压越限时 PVD_IRQHandler 打印信息

1. 使能时钟并配置中断。 main 使能 PWR 与 BKP 时钟,然后调用中断配置函数,再设置 PVD 阈值并等待检测器就绪。

src/main.csrc/main.c · main
    /* Enable PWR and BKP clock */
    RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPHEN_PWR | RCC_APB1_PERIPHEN_BKP, ENABLE);
    /* Configure EXTI Line to generate an interrupt on falling edge */
    EXTI_Configuration();
    /* NVIC configuration */
    NVIC_Configuration();
    /* Configure the PVD Level to 2.58V */
    PWR_PVDLevelConfig(PWR_PVD_LEVEL_2V58);
    /* Enable the PVD Output */
    PWR_PvdEnable(ENABLE);
    /* Wait PVD ready for output */
    while(PWR_GetFlagStatus(PWR_FLAG_PVDRDF) == RESET);
    log_info("\r\n PVD is enabled!\r\n");

PWR_PVD_LEVEL_2V58 决定触发阈值;PWR_GetFlagStatus(PWR_FLAG_PVDRDF) 就绪后再使用输出,移植时按供电电压范围选择阈值。

2. 配置外部中断线与触发边沿。 EXTI_Configuration 清除挂起位并把 PVD 输出映射到 EXTI 第 16 线,上升沿与下降沿都触发。

src/main.csrc/main.c · EXTI_Configuration
    EXTI_InitType EXTI_InitStructure;
    /* Configure EXTI Line16(PVD Output) to generate an interrupt on rising and
       falling edges */
    EXTI_ClrITPendBit(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_InitPeripheral(&EXTI_InitStructure);

EXTI_Trigger_Rising_Falling 使电压升高和降低时都能进入中断,便于观察越限状态的变化。

3. 中断服务程序打印并清标志。 PVD_IRQHandler 判断第 16 线状态,打印提示后清除挂起位。

src/n32h49x_it.csrc/n32h49x_it.c · PVD_IRQHandler
void PVD_IRQHandler(void)
{
    if (EXTI_GetStatusFlag(EXTI_LINE16) != RESET)
    {
        log_info("\r\n Enter PVD interrupt \r\n");
        
        /* Clear the Key Button EXTI line pending bit */
        EXTI_ClrITPendBit(EXTI_LINE16);
    }
}

中断服务程序必须清除挂起位,否则会反复进入中断。

对应源码: src/main.c、src/n32h49x_it.c

5.21.3.2 SLEEP 模式

工程目录: projects/n32h49x_EVAL/examples/PWR/SLEEP/

使能电源管理时钟→配置唤醒按键及其外部中断→进入 SLEEP 模式等待唤醒→按键唤醒后退出并打印

项目 源码解读
功能 使按键 PA0 的上升沿中断把 MCU 从 SLEEP 模式唤醒;
主循环周期性进入 SLEEP 模式以降低功耗,唤醒后打印提示信息
源码组成 src/main.c:main、delay、KeyInputExtiInit;
src/n32h49x_it.c:KEY_EXTI_IRQHandler;
inc/main.h、inc/n32h49x_it.h:头文件;
readme.txt:功能、环境与使用说明;
MDK-ARM/、EWARM/:Keil 与 IAR 工程
关键配置 时钟:系统时钟 240MHz;
引脚:唤醒按键接 PA0,配置为浮空输入并映射到 EXTI0,上升沿触发;
唤醒:PWR_EnterSLEEPMode(PWR_SLEEP_NOW, PWR_SLEEPENTRY_WFI) 以 WFI 进入 SLEEP
程序与数据路径 main 使能 PWR 时钟后调用 KeyInputExtiInit 配置按键中断;
主循环延时后调用 PWR_EnterSLEEPMode 进入 SLEEP,等待按键中断唤醒;
唤醒后在 KEY_EXTI_IRQHandler 中清除中断标志,主循环继续打印
主要 API PWR_EnterSLEEPMode
验证方法 编译烧录后串口打印“Entry SLEEP mode”;
按下 PA0 唤醒按键后打印“Exit SLEEP mode”,串接电流表可见电流先变小再变大
使用提示 硬件平台为全功能板 N32H497ZGL7_EVB V1.0;
开发环境为 KEIL MDK-ARM 5.34 或 IAR EWARM 8.50.1;
唤醒按键为 PA0;
评估功耗时应关闭打印输出
核心代码解读与移植

示例使能 PWR 时钟并把 PA0 配置为上升沿中断,主循环周期性进入 SLEEP 模式,靠按键中断唤醒。

数据路径: main 使能 PWR 时钟 → KeyInputExtiInit 配置 PA0 与 EXTI0 → 主循环延时后 PWR_EnterSLEEPMode 进入 SLEEP → KEY_EXTI_IRQHandler 清除标志并唤醒 → 主循环继续

1. 配置唤醒按键。 KeyInputExtiInit 使能 GPIO 时钟,把 PA0 配置为浮空输入,映射到 EXTI0 并配置上升沿触发与中断优先级。

src/main.csrc/main.c · KeyInputExtiInit
    /* Enable the GPIO Clock */
    RCC_EnableAHB1PeriphClk(RCC_AHB_PERIPHEN_GPIOA, ENABLE);

    /*Configure the GPIO pin as input floating*/
    GPIO_InitStruct(&GPIO_InitStructure);
    GPIO_InitStructure.Pin        = Pin;
    GPIO_InitStructure.GPIO_Mode  = GPIO_MODE_INPUT;
    GPIO_InitPeripheral(GPIOx, &GPIO_InitStructure);

    /*Configure key EXTI Line to key input  Pin*/
    GPIO_ConfigEXTILine(KEY_EXTI_LINE_SOURCE, GPIOA_PORT_SOURCE, KEY_GPIO_PIN_SOURCE);

    /*Configure key EXTI line*/
    EXTI_InitStructure.EXTI_Line = KEY_EXTI_LINE;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_InitPeripheral(&EXTI_InitStructure);

    /*Set key input interrupt priority*/
    NVIC_InitStructure.NVIC_IRQChannel                   = KEY_EXTI_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x05;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0x0F;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

KEY_EXTI_LINE 等宏在 inc/main.h 中定义为 PA0 与 EXTI0,移植到其它引脚时只需修改这些宏。

2. 进入 SLEEP 并等待唤醒。 main 使能 PWR 时钟后清除中断标志,主循环延时后以 WFI 指令进入 SLEEP,唤醒后打印提示并再次进入。

src/main.csrc/main.c · main
    /* Enable PWR Clock */
    RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPHEN_PWR, ENABLE);
    /* Initialize Key button Interrupt to wake up the low power*/
    KeyInputExtiInit(KEY_INPUT_PORT, KEY_INPUT_PIN);
    /* Clear the Interrupt flag */
    EXTI_ClrITPendBit(KEY_EXTI_LINE);
    delay(800);
    
    while (1)
    {
       /* Insert a long delay */
       delay(800);
       log_info("Entry SLEEP mode\n");
       /* Request to enter SLEEP mode*/
       PWR_EnterSLEEPMode(PWR_SLEEP_NOW, PWR_SLEEPENTRY_WFI);
       log_info("Exit SLEEP mode\n");
    }

PWR_SLEEPENTRY_WFI 表示用 WFI 指令进入 SLEEP,任何中断都能唤醒;进入前应清除无关的挂起标志。

3. 中断服务程序清除挂起位。 KEY_EXTI_IRQHandler 在按键中断到来时判断 EXTI0 状态并清除挂起位,使 MCU 从 SLEEP 唤醒后主循环继续运行。

src/n32h49x_it.csrc/n32h49x_it.c · KEY_EXTI_IRQHandler
void KEY_EXTI_IRQHandler(void)
{
    if (EXTI_GetStatusFlag(KEY_EXTI_LINE) != RESET)
    {
       /* Clear the Key Button EXTI line pending bit */
       EXTI_ClrITPendBit(KEY_EXTI_LINE);
    }
}

唤醒后必须在中断服务程序中清除挂起位,否则会反复进入中断而无法返回主循环。

对应源码: src/main.c

5.21.3.3 STOP 模式

工程目录: projects/n32h49x_EVAL/examples/PWR/STOP/

使能电源管理时钟→配置唤醒按键及其外部中断→进入 STOP 模式等待唤醒→唤醒后重新配置系统时钟→退出并打印

项目 源码解读
功能 使按键 PA0 的上升沿中断把 MCU 从 STOP 模式唤醒;
唤醒后重新配置系统时钟,主循环打印提示信息并再次进入 STOP
源码组成 src/main.c:main、delay、KeyInputExtiInit、SetSysClockToPLL;
src/n32h49x_it.c:KEY_EXTI_IRQHandler;
inc/main.h、inc/n32h49x_it.h:头文件;
readme.txt:功能、环境与使用说明;
MDK-ARM/、EWARM/:Keil 与 IAR 工程
关键配置 时钟:系统时钟 240MHz,唤醒后以 HSI 重新配置 PLL 到 160MHz;
引脚:唤醒按键接 PA0,映射到 EXTI0,上升沿触发;
唤醒:PWR_EnterSTOPMode(PWR_REGULATOR_NORMAL, PWR_STOPENTRY_WFI) 以 WFI 进入 STOP
程序与数据路径 main 使能 PWR 时钟后调用 KeyInputExtiInit 配置按键中断;
主循环延时后调用 PWR_EnterSTOPMode 进入 STOP 模式;
唤醒后调用 SetSysClockToPLL 以 HSI 重新配置时钟,并重新初始化日志
主要 API PWR_EnterSTOPMode
验证方法 编译烧录后串口打印“Entry STOP mode”;
按下 PA0 唤醒后打印“Exit STOP mode”,串接电流表可见电流先变小再变大
使用提示 硬件平台为全功能板 N32H497ZGL7_EVB V1.0;
开发环境为 KEIL MDK-ARM 5.34 或 IAR EWARM 8.50.1;
唤醒按键为 PA0,唤醒后时钟从 HSI 重新起步;
评估功耗时应关闭打印输出
核心代码解读与移植

示例在 SLEEP 的基础上增加唤醒后的系统时钟重配置:进入 STOP 时保留寄存器内容,唤醒后由 HSI 重新建立系统时钟。

数据路径: main 使能 PWR 时钟 → KeyInputExtiInit 配置按键中断 → PWR_EnterSTOPMode 进入 STOP → 唤醒后 SetSysClockToPLL 重配时钟 → 重新初始化日志

1. 进入 STOP 并在唤醒后重配时钟。 main 配置按键中断后进入 STOP 模式,唤醒后立即重新配置系统时钟并重新初始化日志。

src/main.csrc/main.c · main
    /* Enable PWR clock */
    RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPHEN_PWR,ENABLE);
    /* Initialize Key button Interrupt to wakeUp stop */
    KeyInputExtiInit(KEY_INPUT_PORT, KEY_INPUT_PIN);
    delay(800);
    
    while (1)
    {
       /* Insert a long delay */
       delay(800);
       log_info("Entry STOP mode\n"); 
       delay(30);
       /* Request to enter STOP mode*/
       PWR_EnterSTOPMode(PWR_REGULATOR_NORMAL, PWR_STOPENTRY_WFI);
       /* Configures system clock after wake-up from STOP: enable HSI, PLL and select
          PLL as system clock source */
       SetSysClockToPLL(RCC_PLL_SRC_HSI,160000000);
       log_init();
       log_info("\nExit STOP mode\n");
    }

PWR_REGULATOR_NORMAL 选择稳压器正常模式;唤醒后必须重新配置时钟,否则串口等外设时钟与波特率不匹配。

2. 唤醒后重新建立系统时钟。 SetSysClockToPLL 用 HSI 作为 PLL 源,按目标频率设置 Flash 等待周期与总线分频,再使能并切换到 PLL。

src/main.csrc/main.c · SetSysClockToPLL
    FLASH_SetLatency(latency);

    /* HCLK = SYSCLK */
    RCC_ConfigHclk(RCC_SYSCLK_DIV1);

    /* PCLK2 */
    RCC_ConfigPclk2(pclk2div);

    /* PCLK1 */
    RCC_ConfigPclk1(pclk1div);
    
    if(PLL_src == RCC_PLL_SRC_HSE)
    {
        RCC_ConfigPll(RCC_PLL_SRC_HSE,pllpre,pllmul, RCC_PLLOUT_DIV_1);
    }
    else
    {
        RCC_ConfigPll(RCC_PLL_SRC_HSI,pllpre,pllmul, RCC_PLLOUT_DIV_1);
    }

    /* Enable PLL */
    RCC_EnablePll(ENABLE);

示例在唤醒时以 RCC_PLL_SRC_HSI 为准,因为 STOP 唤醒后 HSE 需要重新起振,用 HSI 起步更稳妥。

3. 配置唤醒按键。 KeyInputExtiInit 把 PA0 配置为浮空输入并映射到 EXTI0 上升沿中断,用于把 MCU 从 STOP 唤醒。

src/main.csrc/main.c · KeyInputExtiInit
    /* Enable the GPIO Clock */
    RCC_EnableAHB1PeriphClk(RCC_AHB_PERIPHEN_GPIOA, ENABLE);

    /*Configure the GPIO pin as input floating*/
    GPIO_InitStruct(&GPIO_InitStructure);
    GPIO_InitStructure.Pin        = Pin;
    GPIO_InitStructure.GPIO_Mode  = GPIO_MODE_INPUT;
    GPIO_InitPeripheral(GPIOx, &GPIO_InitStructure);

    /*Configure key EXTI Line to key input  Pin*/
    GPIO_ConfigEXTILine(KEY_EXTI_LINE_SOURCE, GPIOA_PORT_SOURCE, KEY_GPIO_PIN_SOURCE);

    /*Configure key EXTI line*/
    EXTI_InitStructure.EXTI_Line = KEY_EXTI_LINE;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_InitPeripheral(&EXTI_InitStructure);

    /*Set key input interrupt priority*/
    NVIC_InitStructure.NVIC_IRQChannel                   = KEY_EXTI_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x05;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0x0F;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

GPIO_MODE_INPUT 为浮空输入;按键按下时 PA0 电平变化产生上升沿,从而触发 EXTI0 唤醒。

对应源码: src/main.c

5.21.3.4 STANDBY 模式

工程目录: projects/n32h49x_EVAL/examples/PWR/STANDBY/

使能电源管理时钟→配置唤醒引脚极性并使能→清除唤醒标志→进入 STANDBY 模式等待唤醒

项目 源码解读
功能 使能 PA0 作为唤醒引脚,MCU 进入 STANDBY 模式;
按下按键产生唤醒事件,芯片复位并从 0 地址重新执行
源码组成 src/main.c:main、delay;
inc/main.h:定义唤醒引脚相关宏;
inc/n32h49x_it.h:头文件;
readme.txt:功能、环境与使用说明;
MDK-ARM/、EWARM/:Keil 与 IAR 工程
关键配置 时钟:系统时钟 240MHz;
唤醒引脚:WAKEUP_PIN1(PA0)极性设为高电平有效并使能;
模式:调用 PWR_EnterSTANDBYMode() 进入 STANDBY,唤醒后系统复位
程序与数据路径 main 使能 PWR 时钟后设置唤醒引脚极性并使能唤醒功能;
主循环先清除可能存在的唤醒标志,延时后调用 PWR_EnterSTANDBYMode 进入 STANDBY;
按下 PA0 产生唤醒事件,芯片复位并从 0 地址重新执行
主要 API PWR_WakeUpPinPolarity、PWR_WakeUpPinEnable、PWR_GetFlagStatus、PWR_ClearFlag、PWR_EnterSTANDBYMode
验证方法 编译烧录后串口打印“Entry STANDBY mode”;
按下 PA0 唤醒后打印“--- Reset for STANDBY ---”,说明已复位重启
使用提示 硬件平台为全功能板 N32H497ZGL7_EVB V1.0;
开发环境为 KEIL MDK-ARM 5.34 或 IAR EWARM 8.50.1;
唤醒引脚为 PA0(WKUP1);
评估功耗时应关闭打印输出
核心代码解读与移植

示例使能唤醒引脚 PA0 并使能唤醒功能,主循环清除唤醒标志后进入 STANDBY 模式;唤醒事件使芯片复位重启。

数据路径: main 使能 PWR 时钟 → PWR_WakeUpPinPolarity 与 PWR_WakeUpPinEnable 配置并使能唤醒引脚 → 主循环清除唤醒标志 → PWR_EnterSTANDBYMode 进入 STANDBY → 唤醒后芯片复位重启

1. 配置并进入 STANDBY 模式。 main 使能 PWR 时钟后设置唤醒引脚极性并使能唤醒,主循环先清除唤醒标志再进入 STANDBY。

src/main.csrc/main.c · main
    /* Enable PWR clock */
    RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPHEN_PWR, ENABLE);
    /* Enable WKUP pin */
    PWR_WakeUpPinPolarity(WAKEUP_PINx_POL, POL_HIGH);
    PWR_WakeUpPinEnable(WAKEUP_PINx_EN, ENABLE);
    delay(800);
    
    while (1)
    {
       /* Check if the Wake-Up flag is set */
       if (PWR_GetFlagStatus(WAKEUP_PINx_FLAG) != RESET)
       {
          /* Clear Wake Up flag */
          PWR_ClearFlag(WAKEUP_PINx_CLR);
       }
       /* Delay a long time */
       delay(800);
       log_info("Entry STANDBY mode\n");
       /* Request to enter STANDBY mode */
       PWR_EnterSTANDBYMode();
    }

POL_HIGH 表示按键按下时 PA0 为高电平产生唤醒事件;进入 STANDBY 前清除唤醒标志可避免上一次的唤起床位导致误判。

2. 唤醒引脚相关宏定义。 inc/main.h 把示例使用的唤醒引脚统一为 WAKEUP_PIN1(PA0)的一组宏,便于替换引脚。

inc/main.hinc/main.h
#define WAKEUP_PINx_POL    WAKEUP_PIN1POL
#define WAKEUP_PINx_EN     WAKEUP_PIN1EN
#define WAKEUP_PINx_FLAG   PWR_FLAG_WKUP1
#define WAKEUP_PINx_CLR    PWR_CLR_WKUP1

宏的四个值一一对应:极性、使能、标志与清除,移植到其它唤醒引脚时同步替换即可。

3. STANDBY 唤醒后的行为。 STANDBY 唤醒会使芯片复位,程序从 0 地址重新运行,串口最先打印复位提示,说明唤醒事件已生效。

src/main.csrc/main.c · main
    log_init(); 
    log_info("\r\n --- Reset for STANDBY --- \r\n");
    
 
    /* Enable PWR clock */
    RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPHEN_PWR, ENABLE);

进入 STANDBY 后除备份域外大部分电路断电,唤醒等同复位,因此不能依靠变量在唤醒后继续执行。

对应源码: src/main.c、inc/main.h

5.21.4 注意与排障

场景 检查与建议 来源
进入 STOP 模式的条件 进入 STOP 模式需同时满足 SLEEPDEEP=1 且电源模式位为 0,并确保所有中断与唤醒事件已就绪;
条件不满足时寄存器保持原值且不进入 STOP。
用户手册
切换时钟源前先关闭 HSE 从 HSE 切换到 HSI 前必须先关闭 HSEEN,并等待 HSE 就绪标志清零;
否则切换不生效。
用户手册
STOP 唤醒后的时钟 STOP 唤醒后系统以 HSI 作为时钟源,需重新配置 PLL 与总线分频;
本示例在唤醒后重新配置系统时钟以恢复所需频率。
用户手册
RTC 闹钟唤醒 使用 RTC 闹钟从 STOP 唤醒时,需使能 EXTI 第 17 线的 RTC 闹钟中断并清除挂起位;
否则无法唤醒。
用户手册
唤醒引脚配置顺序 修改唤醒引脚极性前应先禁止该唤醒引脚,配置完成后再使能;
避免配置过程中产生误唤醒。
用户手册
清除待机标志 STANDBY 与 VBAT 标志通过写 1 清除;
上电后应先读取并清除这些标志再判断唤醒来源。
用户手册
备份域寄存器解锁 写备份域寄存器前需向电源控制寄存器写入解锁口令,随后置位备份域写使能;
完成后应重新上锁。
用户手册
1.8V 外设上电顺序 1.8V 域外设应分批上电,每批不超过 4 个外设且相邻批次间隔不小于 1ms;
避免同时上电造成冲击。
用户手册
国民技术开发套件文档中心

按芯片系列在线查阅国民技术 MCU 开发套件的芯片资料、SDK、驱动 API 与 Demo 示例说明。

© 2026 国民技术股份有限公司 版权所有粤ICP备11069485号本站使用不含 Cookie 的匿名访问统计