5.21 PWR Guide
This chapter describes the file composition and 30 public functions of the PWR driver in the N32H49x standard peripheral library, together with the PVD, SLEEP, STOP and STANDBY examples. The power management unit handles voltage monitoring, wake-up source enabling and low-power mode switching; the conditions for entering SLEEP, STOP and STANDBY, the clock state after wake-up and the backup-domain access rules are described in the “Power management (PWR)” chapter of the user manual.
5.21.1 Related files
| Relative path | Purpose |
|---|---|
firmware/n32h49x_std_periph_driver/inc/n32h49x_pwr.h |
Defines the PVD levels, wake-up pins and flag values, and declares the 30 public functions |
firmware/n32h49x_std_periph_driver/src/n32h49x_pwr.c |
Implements the 30 functions above: voltage monitoring, wake-up configuration, low-power entry, flags and reset, backup-domain control |
projects/n32h49x_EVAL/examples/PWR/ |
PWR example root directory, containing the PVD, SLEEP, STOP and STANDBY examples |
projects/n32h49x_EVAL/examples/PWR/PVD/ |
Project directory composition of this example: MDK-ARM/, EWARM/, inc/, src/, readme.txt |
projects/n32h49x_EVAL/bsp/ |
Common board files referenced by this example: the UART log and delay functions |
5.21.2 API reference
The following 30 public functions are listed in the declaration order of n32h49x_pwr.h in 8 groups; each entry gives a summary and the original comment above the function in n32h49x_pwr.c.
Basics and backup domain
PWR_DeInit, PWR_BackupAccessEnable
PVD voltage monitoring
PWR_PvdEnable, PWR_PVDLevelConfig, PWR_PVDSourceConfig, PWR_PVDINPinSelect
Wake-up pins and peripherals
PWR_WakeUpPinEnable, PWR_WakeUpPinPolarity, PWR_WakeUpPeriphEnable
Low-power modes
PWR_EnterSLEEPMode, PWR_EnterSTOPMode, PWR_EnterSTANDBYMode
Flags and reset
PWR_GetFlagStatus, PWR_ClearFlag, PWR_EnableIWDGReset
BKR and backup SRAM
PWR_ConfigBKROutput, PWR_EnableBKPSRAMRetainInStandbyMode, PWR_EnableBKPSRAMRetainInVbatMode
LSE clock security system
PWR_EnableLSENoiseMitigation, PWR_EnableLSECSSCrystalInt, PWR_ConfigLSECSSBypassHighLimit, PWR_EnableLSECSSRTCsourceSwitch, PWR_GetLSECSSFlagStatus, PWR_ClearLSECSSFlag
LCO and NRST
PWR_ConfigLco, PWR_EnableLCO, PWR_EnableNRSTOut, PWR_ConfigNRSTDigitalFilterWidth, PWR_EnableNRSTDigitalFilter, PWR_EnableNRSTAnalogFilter
void PWR_DeInit(void)Deinitializes the PWR peripheral registers to their default reset values.
name PWR_DeInit.
fun Deinitializes the PWR peripheral registers to their default reset values.
param none
return none
void PWR_BackupAccessEnable(FunctionalState Cmd)Enables or disables access to the RTC and backup registers.
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)Enables or disables the Power Voltage Detector(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)Configures the voltage threshold detected by the Power Voltage Detector(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 Source selection.
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 pin selection.
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)Enables the Wakeup Pin functionality.
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)Enables the Wakeup Pin 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)Enables the Wakeup periph functionality.
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)Enters SLEEP mode.
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)Enters STOP mode.
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)Enters STANDBY mode.
name PWR_EnterSTANDBYMode.
fun Enters STANDBY mode.
param none
return none
FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG)Checks whether the specified PWR flag is set or not.
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)Clears the PWR’s pending flags.
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)Selects the BKR regulator output level.
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)Configure whether to generate a reset request when the IWDG counter reaches 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)Enable or disable BKP SRAM retain in standby mode.
name PWR_EnableBKPSRAMRetainInStandbyMode.
fun Enable or disable BKP SRAM retain in standby mode.
param Cmd:
- ENABLE
- DISABLE
return none.
void PWR_EnableBKPSRAMRetainInVbatMode(FunctionalState Cmd)Enable or disable BKP SRAM retain in Vbat mode.
name PWR_EnableBKPSRAMRetainInVbatMode.
fun Enable or disable BKP SRAM retain in Vbat mode.
param Cmd:
- ENABLE
- DISABLE
return none.
void PWR_EnableLSENoiseMitigation(FunctionalState Cmd)Enable or disable LSE noise mitigation.
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)Enable or disable LSE Clock Safety System Interrupt in Crystal Mode.
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)Configuring the LSE Frequency High Limit for Bypass Mode.
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)Enable or disable switching the RTC clock source from LSE to LSI when the LSE clock fails.
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)Checks whether the specified PWR LSECSS flag is set or not.
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)Clears the LSECSS all flags.
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 low-speed clock output selection.
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)Enable or disable low-speed clock output
name PWR_EnableLCO.
fun Enable or disable low-speed clock output
param Cmd:
- ENABLE
- DISABLE
return none
void PWR_EnableNRSTOut(FunctionalState Cmd)Enable or disable the output function of NRST Pin.
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)Configuring the NRST digital filter width.
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)Enable or disable NRST digital filter
name PWR_EnableNRSTDigitalFilter.
fun Enable or disable NRST digital filter
param Cmd:
- ENABLE
- DISABLE
return none
void PWR_EnableNRSTAnalogFilter(FunctionalState Cmd)Enable or disable NRST Analog filter
name PWR_EnableNRSTAnalogFilter.
fun Enable or disable NRST Analog filter
param Cmd:
- ENABLE
- DISABLE
return none
5.21.3 Demo descriptions
This section describes the four PWR examples: PVD generates an interrupt from voltage detection, and SLEEP, STOP and STANDBY demonstrate low-power mode entry and wake-up.
5.21.3.1 PVD voltage monitoring
Example directory: projects/n32h49x_EVAL/examples/PWR/PVD/
Enable the power management clock→Configure the external interrupt line for voltage detection→Set the threshold and enable detection→Trigger an interrupt and print when the voltage crosses the threshold
| Item | Source analysis |
|---|---|
| Function | Monitors the supply voltage with the power voltage detector; when the voltage crosses the 2.58 V threshold an interrupt is triggered on the rising or falling edge and a message is printed in the handler. |
| Source files | src/main.c: main, EXTI_Configuration, NVIC_Configuration;src/n32h49x_it.c: PVD_IRQHandler;inc/main.h, inc/n32h49x_it.h: header files;readme.txt: function, environment and usage notes;MDK-ARM/, EWARM/: Keil and IAR projects. |
| Key configuration | Clock: system clock 240 MHz; Interrupt: the PVD output is connected to EXTI line 16, both edges trigger, and the PVD interrupt is enabled with a priority; Detection: the threshold is set to 2.58 V. |
| Program and data path | main first enables the PWR and BKP clocks, then configures the external interrupt line and the NVIC;it then sets the PVD threshold and enables the PVD and waits for PWR_FLAG_PVDRDF;when the voltage crosses the threshold PVD_IRQHandler prints a message and clears the interrupt flag. |
| Main APIs | PWR_PVDLevelConfig, PWR_PvdEnable, PWR_GetFlagStatus |
| Verification | After building and downloading, the UART prints “This is a PVD demo” and “PVD is enabled!”; adjust the voltage near 2.58 V and the program enters PVD_IRQHandler and prints “Enter PVD interrupt”. |
| Use note | The hardware platform is the full-featured board N32H497ZGL7_EVB V1.0; the development environment is KEIL MDK-ARM 5.34 or IAR EWARM 8.50.1; the print UART is USART1 (TX PA9, RX PA10, 115200); the PVD interrupt fires when the voltage crosses the threshold, so an adjustable analog voltage must be provided externally. |
Core-code walkthrough and porting
The example first enables the PWR and BKP clocks, then configures the external interrupt line and the interrupt vector for the PVD output, sets the threshold and enables the PVD, and finally waits for the voltage to cross the threshold and trigger the interrupt.
Data path: main enables the PWR and BKP clocks → EXTI_Configuration configures EXTI line 16 → NVIC_Configuration enables the PVD interrupt → main sets the threshold and enables the PVD → PVD_IRQHandler prints a message when the voltage crosses the threshold
1. Enable the clocks and configure the interrupt. main enables the PWR and BKP clocks, calls the interrupt configuration functions, then sets the PVD threshold and waits for the detector to be ready.
/* 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 sets the trigger threshold; the detector is used only after PWR_GetFlagStatus(PWR_FLAG_PVDRDF) is ready, and when porting choose the level that fits the supply range.
2. Configure the external interrupt line and edge. EXTI_Configuration clears the pending bit and maps the PVD output to EXTI line 16, with both the rising and falling edges triggering.
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 lets the interrupt fire both when the voltage rises and when it falls, so the crossing behaviour is easy to observe.
3. Print and clear the flag in the handler. PVD_IRQHandler checks the state of line 16, prints a message and clears the pending bit.
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);
}
}
The handler must clear the pending bit, otherwise the interrupt is entered repeatedly.
Corresponding source files: src/main.c, src/n32h49x_it.c
5.21.3.2 SLEEP mode
Example directory: projects/n32h49x_EVAL/examples/PWR/SLEEP/
Enable the power management clock→Configure the wake-up button and its external interrupt→Enter SLEEP and wait for wake-up→Exit and print after the button wakes the core
| Item | Source analysis |
|---|---|
| Function | Uses the rising-edge interrupt of button PA0 to wake the MCU from SLEEP; the main loop enters SLEEP periodically to reduce power and prints a message after wake-up. |
| Source files | src/main.c: main, delay, KeyInputExtiInit;src/n32h49x_it.c: KEY_EXTI_IRQHandler;inc/main.h, inc/n32h49x_it.h: header files;readme.txt: function, environment and usage notes;MDK-ARM/, EWARM/: Keil and IAR projects. |
| Key configuration | Clock: system clock 240 MHz; Pins: the wake-up button is on PA0, configured as floating input and mapped to EXTI0, rising-edge trigger; Wake-up: PWR_EnterSLEEPMode(PWR_SLEEP_NOW, PWR_SLEEPENTRY_WFI) enters SLEEP with WFI. |
| Program and data path | main enables the PWR clock and calls KeyInputExtiInit to configure the button interrupt;the main loop delays and then calls PWR_EnterSLEEPMode to enter SLEEP and waits for the button interrupt;after wake-up KEY_EXTI_IRQHandler clears the interrupt flag and the main loop keeps printing. |
| Main APIs | PWR_EnterSLEEPMode |
| Verification | After building and downloading, the UART prints “Entry SLEEP mode”; press the PA0 wake-up button and it prints “Exit SLEEP mode”, and an ammeter in series shows the current first dropping and then rising. |
| Use note | The hardware platform is the full-featured board N32H497ZGL7_EVB V1.0; the development environment is KEIL MDK-ARM 5.34 or IAR EWARM 8.50.1; the wake-up button is PA0; turn off the print output when measuring power consumption. |
Core-code walkthrough and porting
The example enables the PWR clock and configures PA0 as a rising-edge interrupt; the main loop enters SLEEP periodically and is woken by the button interrupt.
Data path: main enables the PWR clock → KeyInputExtiInit configures PA0 and EXTI0 → the main loop delays and calls PWR_EnterSLEEPMode to enter SLEEP → KEY_EXTI_IRQHandler clears the flag and wakes the core → the main loop continues
1. Configure the wake-up button. KeyInputExtiInit enables the GPIO clock, configures PA0 as floating input, maps it to EXTI0 and sets the rising-edge trigger and the interrupt priority.
/* 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);
The macros such as KEY_EXTI_LINE are defined in inc/main.h as PA0 and EXTI0, so porting to another pin only needs these macros changed.
2. Enter SLEEP and wait for wake-up. main enables the PWR clock and clears the interrupt flag; the main loop enters SLEEP with the WFI instruction after a delay and, once woken, prints a message and enters again.
/* 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 enters SLEEP with the WFI instruction and any interrupt can wake the core, so unrelated pending flags should be cleared before entering.
3. Clear the pending bit in the handler. KEY_EXTI_IRQHandler checks the EXTI0 state on the button interrupt and clears the pending bit, so the main loop continues after the MCU is woken from SLEEP.
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);
}
}
The pending bit must be cleared in the handler after wake-up, otherwise the interrupt is entered repeatedly and the main loop is never resumed.
Corresponding source files: src/main.c
5.21.3.3 STOP mode
Example directory: projects/n32h49x_EVAL/examples/PWR/STOP/
Enable the power management clock→Configure the wake-up button and its external interrupt→Enter STOP and wait for wake-up→Reconfigure the system clock after wake-up→Exit and print
| Item | Source analysis |
|---|---|
| Function | Uses the rising-edge interrupt of button PA0 to wake the MCU from STOP; after wake-up it reconfigures the system clock and the main loop prints a message and enters STOP again. |
| Source files | src/main.c: main, delay, KeyInputExtiInit, SetSysClockToPLL;src/n32h49x_it.c: KEY_EXTI_IRQHandler;inc/main.h, inc/n32h49x_it.h: header files;readme.txt: function, environment and usage notes;MDK-ARM/, EWARM/: Keil and IAR projects. |
| Key configuration | Clock: system clock 240 MHz, and after wake-up the PLL is reconfigured to 160 MHz from HSI; Pins: the wake-up button is on PA0, mapped to EXTI0, rising-edge trigger; Wake-up: PWR_EnterSTOPMode(PWR_REGULATOR_NORMAL, PWR_STOPENTRY_WFI) enters STOP with WFI. |
| Program and data path | main enables the PWR clock and calls KeyInputExtiInit to configure the button interrupt;the main loop delays and then calls PWR_EnterSTOPMode to enter STOP;after wake-up it calls SetSysClockToPLL to reconfigure the clock from HSI and re-initializes the log. |
| Main APIs | PWR_EnterSTOPMode |
| Verification | After building and downloading, the UART prints “Entry STOP mode”; press the PA0 button and it prints “Exit STOP mode”, and an ammeter in series shows the current first dropping and then rising. |
| Use note | The hardware platform is the full-featured board N32H497ZGL7_EVB V1.0; the development environment is KEIL MDK-ARM 5.34 or IAR EWARM 8.50.1; the wake-up button is PA0, and the clock restarts from HSI after wake-up; turn off the print output when measuring power consumption. |
Core-code walkthrough and porting
On top of SLEEP the example adds a system clock reconfiguration after wake-up: entering STOP keeps the register contents and the wake-up path re-establishes the system clock from HSI.
Data path: main enables the PWR clock → KeyInputExtiInit configures the button interrupt → PWR_EnterSTOPMode enters STOP → SetSysClockToPLL reconfigures the clock after wake-up → the log is re-initialized
1. Enter STOP and reconfigure the clock after wake-up. main configures the button interrupt and enters STOP; once woken it immediately reconfigures the system clock and re-initializes the log.
/* 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 selects the normal regulator mode; the clock must be reconfigured after wake-up, otherwise the peripheral clocks such as the UART no longer match the baud rate.
2. Re-establish the system clock after wake-up. SetSysClockToPLL uses HSI as the PLL source, sets the Flash latency and bus prescalers for the target frequency, then enables and switches to the PLL.
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);
The example uses RCC_PLL_SRC_HSI on wake-up because HSE needs to restart after STOP, so starting from HSI is more robust.
3. Configure the wake-up button. KeyInputExtiInit configures PA0 as floating input and maps it to the EXTI0 rising-edge interrupt used to wake the MCU from STOP.
/* 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 is floating input; pressing the button changes the PA0 level and produces a rising edge that triggers the EXTI0 wake-up.
Corresponding source files: src/main.c
5.21.3.4 STANDBY mode
Example directory: projects/n32h49x_EVAL/examples/PWR/STANDBY/
Enable the power management clock→Set the wake-up pin polarity and enable it→Clear the wake-up flag→Enter STANDBY and wait for the wake-up event
| Item | Source analysis |
|---|---|
| Function | Enables PA0 as a wake-up pin and puts the MCU into STANDBY; pressing the button produces a wake-up event and the chip resets and restarts from address 0. |
| Source files | src/main.c: main, delay;inc/main.h: defines the wake-up pin macros;inc/n32h49x_it.h: header file;readme.txt: function, environment and usage notes;MDK-ARM/, EWARM/: Keil and IAR projects. |
| Key configuration | Clock: system clock 240 MHz; Wake-up pin: WAKEUP_PIN1 (PA0) with high active polarity and enabled;Mode: PWR_EnterSTANDBYMode() enters STANDBY and the system resets on wake-up. |
| Program and data path | main enables the PWR clock, sets the wake-up pin polarity and enables the wake-up function;the main loop clears any pending wake-up flag, delays and then calls PWR_EnterSTANDBYMode to enter STANDBY;pressing PA0 produces a wake-up event and the chip resets and restarts from address 0. |
| Main APIs | PWR_WakeUpPinPolarity, PWR_WakeUpPinEnable, PWR_GetFlagStatus, PWR_ClearFlag, PWR_EnterSTANDBYMode |
| Verification | After building and downloading, the UART prints “Entry STANDBY mode”; press the PA0 button and it prints “--- Reset for STANDBY ---”, showing the chip has reset and restarted. |
| Use note | The hardware platform is the full-featured board N32H497ZGL7_EVB V1.0; the development environment is KEIL MDK-ARM 5.34 or IAR EWARM 8.50.1; the wake-up pin is PA0 (WKUP1); turn off the print output when measuring power consumption. |
Core-code walkthrough and porting
The example enables the PA0 wake-up pin and the wake-up function, clears the wake-up flag in the main loop and then enters STANDBY; the wake-up event resets and restarts the chip.
Data path: main enables the PWR clock → PWR_WakeUpPinPolarity and PWR_WakeUpPinEnable configure and enable the wake-up pin → the main loop clears the wake-up flag → PWR_EnterSTANDBYMode enters STANDBY → the chip resets and restarts on wake-up
1. Configure and enter STANDBY. main enables the PWR clock, sets the wake-up pin polarity and enables the wake-up function, and the main loop clears the wake-up flag before entering STANDBY.
/* 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 means the PA0 high level produced when the button is pressed wakes the chip; clearing the wake-up flag before entering STANDBY avoids a stale latched wake-up causing a misjudgement.
2. Wake-up pin macro definitions. inc/main.h groups the wake-up pin used by the example into a set of macros for WAKEUP_PIN1 (PA0), which is easy to replace.
#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
The four macros correspond to the polarity, the enable, the flag and the clear value; replace them together when porting to another wake-up pin.
3. Behaviour after STANDBY wake-up. STANDBY wake-up resets the chip, so the program restarts from address 0 and the UART prints the reset message first, showing the wake-up event has taken effect.
log_init();
log_info("\r\n --- Reset for STANDBY --- \r\n");
/* Enable PWR clock */
RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPHEN_PWR, ENABLE);
After entering STANDBY most circuits except the backup domain are powered down and wake-up is equivalent to a reset, so the application cannot rely on variables surviving the wake-up.
Corresponding source files: src/main.c, inc/main.h
5.21.4 Notes and troubleshooting
| Scenario | Check & action | Source |
|---|---|---|
| Conditions for entering STOP | Entering STOP requires SLEEPDEEP to be 1 and the power mode bit to be 0, with all interrupts and wake-up events ready; when a condition is not met the registers keep their values and STOP is not entered. |
User manual |
| Disable HSE before switching the clock source | Before switching from HSE to HSI, HSEEN must be cleared and the HSE ready flag must be waited to be zero; otherwise the switch does not take effect. |
User manual |
| Clock after STOP wake-up | After STOP wake-up the system uses HSI as the clock source, so the PLL and bus prescalers must be reconfigured; this example reconfigures the system clock after wake-up to restore the required frequency. |
User manual |
| RTC alarm wake-up | To wake from STOP with the RTC alarm, enable the EXTI line 17 RTC alarm interrupt and clear the pending bit; otherwise the core cannot be woken. |
User manual |
| Wake-up pin configuration order | Disable the wake-up pin before changing its polarity and enable it again after the configuration; this avoids a spurious wake-up during configuration. |
User manual |
| Clearing the standby flags | The STANDBY and VBAT flags are cleared by writing 1; read and clear them at power-up before deciding the wake-up source. |
User manual |
| Unlocking the backup domain | Before writing backup-domain registers, write the unlock key to the power control register and then set the backup-domain write enable; lock it again afterwards. |
User manual |
| 1.8 V peripheral power-up order | Power up the 1.8 V domain peripherals in batches of no more than 4 with at least 1 ms between batches; this avoids the inrush caused by powering all of them at once. |
User manual |