5.14 PWR Guide
This chapter describes the file composition and the 9 public functions of the PWR driver in the N32G033 standard peripheral library, together with the 2 examples PVD and STOP. Read the power modes, the programmable voltage detector and the peripheral state in each mode together with the “Power control (PWR)” chapter of the user manual; for known silicon issues, refer to the errata sheet.
5.14.1 Related files
| Relative path | Purpose |
|---|---|
firmware/n32g033_std_periph_driver/inc/n32g033_pwr.h |
Defines the macros for PVD voltage level, PVD/NRST filter width, STOP entry mode and debug peripherals, and declares the 9 public functions in four sections: voltage monitoring, reset filter and watchdog, low power and write protection, debug peripherals |
firmware/n32g033_std_periph_driver/src/n32g033_pwr.c |
Implements the 9 functions above: PVD enable, filter and threshold, NRST filter, STOP entry, write protection, flag query and debug peripheral configuration |
projects/n32g033_EVAL/examples/PWR/ |
PWR example root directory, containing 2 examples: PVD and STOP |
projects/n32g033_EVAL/examples/PWR/PVD/ |
Example directory composition: MDK-ARM/, EWARM/, inc/, src/, readme.txt |
projects/n32g033_EVAL/bsp/inc/, projects/n32g033_EVAL/bsp/src/ |
Board-level common files; the examples use log.h for serial logging |
5.14.2 API reference
The 9 public functions below are grouped into 4 groups in the declaration order of n32g033_pwr.h; each entry gives a function summary and the source comment verbatim above that function in n32g033_pwr.c.
Voltage monitoring
PWR_PvdEnable, PWR_PVDFilterWidthSet, PWR_PVDLevelConfig, PWR_GetFlagStatus
Reset filter and watchdog
PWR_NRSTFilterWidthSet, PWR_EnableIWDGReset
Low power and write protection
PWR_EnterSTOPMode, PWR_CTRL2WriteProtectionEnable
Debug peripheral configuration
DBG_ConfigPeriph
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_PVDFilterWidthSet(uint8_t filter_value)Adjusting the PVD Filter Control Count value.
name PWR_PVDFilterWidthSet.
fun Adjusting the PVD Filter Control Count value.
param filter_value(Filter Width = (1/fLSI) * filter_value):
-0 ~ 0x1F
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_2V0
- PWR_PVD_LEVEL_2V2
- PWR_PVD_LEVEL_2V4
- PWR_PVD_LEVEL_2V6
- PWR_PVD_LEVEL_2V8
- PWR_PVD_LEVEL_3V0
- PWR_PVD_LEVEL_3V2
- PWR_PVD_LEVEL_3V4
- PWR_PVD_LEVEL_3V6
- PWR_PVD_LEVEL_3V8
- PWR_PVD_LEVEL_4V0
- PWR_PVD_LEVEL_4V2
- PWR_PVD_LEVEL_4V4
- PWR_PVD_LEVEL_4V6
- PWR_PVD_LEVEL_4V8
return none
void PWR_NRSTFilterWidthSet(uint16_t filter_value)Adjusting the NRST Filter Control Count value.
name PWR_NRSTFilterWidthSet.
fun Adjusting the NRST Filter Control Count value.
param filter_value(Filter Width = (1/fSYSCLK) * filter_value):
-0 ~ 0xF
return none
void PWR_EnterSTOPMode(uint8_t enter_mode)Enters STOP mode.
name PWR_EnterSTOPMode.
fun Enters STOP mode.
param enter_mode (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_CTRL2WriteProtectionEnable(void)Enable the PWR_CTRL2 registers write protection.
name PWR_CTRL2WriteProtectionEnable.
fun Enable the PWR_CTRL2 registers write protection.
param none
return none
note This register has write protection.Before writing PWR_CTRL2, PWR_CTRL2WriteProtectionEnable()
function must be called, and then write real value to PWR_CTRL2
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 flag (The input parameters must be the following values):
- PWR_PVDO_FLAG PVD Output flag
return SET or RESET.
void DBG_ConfigPeriph(uint32_t DBG_Periph, FunctionalState Cmd)Configures the specified peripheral run when the MCU under Debug mode.
name DBG_ConfigPeriph.
fun Configures the specified peripheral run when the MCU under Debug mode.
param DBG_Periph (The input parameters must be the following values):
- PWR_DBG_IWDG IWDG stopped when Core is halted
- PWR_DBG_TIM1 TIM1 counter stopped when Core is halted
- PWR_DBG_TIM3 TIM3 counter stopped when Core is halted
- PWR_DBG_TIM4 TIM4 counter stopped when Core is halted
- PWR_DBG_I2C1 I2C1 SMBUS timeout mode stopped stopped when Core is halted
- PWR_DBG_I2C2 I2C2 SMBUS timeout mode stopped stopped when Core is halted
- PWR_DBG_TIM6 TIM6 counter stopped when Core is halted
param Cmd:
- ENABLE
- DISABLE
return 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.
5.14.3 Demo descriptions
This section describes the 2 PWR examples: PVD compares the VDD voltage with a configured threshold and enters an interrupt when it crosses it, and STOP enters low-power mode and resumes after a key pin wakes it up.
5.14.3.1 PVD voltage-monitoring interrupt
Example directory: projects/n32g033_EVAL/examples/PWR/PVD/
Enable the power-management clock→configure the external interrupt line for the voltage crossing→enable the interrupt channel→set the monitoring voltage threshold and turn on monitoring→enter the interrupt service and print a hint when the voltage crosses the threshold
| Item | Source analysis |
|---|---|
| Function | Turn on PVD with a monitoring threshold of 2.4 V, so that when VDD crosses the threshold it enters the PVD interrupt through the external interrupt line. |
| Source files | src/main.c contains EXTI_Configuration and NVIC_Configuration;src/n32g033_it.c contains PVD_IRQHandler;inc/main.h gives the declarations and peripheral headers;readme.txt gives the configuration and test steps;project files are in MDK-ARM/ and EWARM/. |
| Key configuration | Interrupt line: EXTI line 7 corresponds to the PVD output, triggered on rising and falling edges; interrupt channel: PVD_IRQn with priority 0;threshold: PWR_PVD_LEVEL_2V4;clock: HSI 64 MHz, log port PA9-115200. |
| Program and data path | main -> log_init initializes logging -> RCC_EnableAPBPeriphClk enables the PWR clock -> EXTI_Configuration clears the line 7 flag and configures rising and falling edges -> NVIC_Configuration enables PVD_IRQn -> PWR_PVDLevelConfig sets the threshold -> PWR_PvdEnable turns on monitoring -> on crossing, PVD_IRQHandler runs. |
| Main APIs | PWR_PVDLevelConfig, PWR_PvdEnable, PWR_GetFlagStatus |
| Verification | After building and burning to the evaluation board, lower the voltage below the configured threshold; the serial port prints Enter PVD interrupt. |
| Use note | The development environment is KEIL MDK-ARM V5.34.0.0 or IAR EWARM 8.50.1; the PVD event is connected internally to external interrupt line 7, so both the external interrupt and the interrupt channel must be configured. |
Core-code walkthrough and porting
The example first enables the PWR clock, then configures the external interrupt and interrupt channel for the voltage crossing, sets the threshold and turns on monitoring, and enters the interrupt service on crossing.
Data path: RCC_EnableAPBPeriphClk enables the PWR clock -> EXTI_Configuration clears the line 7 flag and sets the trigger edges -> NVIC_Configuration enables PVD_IRQn -> PWR_PVDLevelConfig writes the threshold level -> PWR_PvdEnable sets PVDEN -> voltage crossing -> PVD_IRQHandler clears the flag
1. First enable the PWR APB clock. PVD belongs to the power-management unit, so the PWR clock must be enabled before configuration.
/* Enable PWR and BKP clock */
RCC_EnableAPBPeriphClk(RCC_APB_PERIPH_PWR, ENABLE);
In another project, if the PWR clock is not enabled the writes to the PWR registers do not take effect.
2. Configure the external interrupt line for the voltage crossing. The PVD output is connected internally to EXTI line 7, so clear the pending bit then set rising and falling edge triggering.
EXTI_InitType EXTI_InitStructure;
/* Configure EXTI Line16(PVD Output) to generate an interrupt on rising and
falling edges */
EXTI_ClrITPendBit(EXTI_LINE7);
EXTI_InitStructure.EXTI_Line = EXTI_LINE7;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_InitPeripheral(&EXTI_InitStructure);
When moving to another chip or changing the trigger, only adjust EXTI_Line and EXTI_Trigger; the other fields stay unchanged.
3. Enable the interrupt channel, set the threshold and turn on monitoring. After NVIC enables the PVD interrupt, write the threshold level and set the PVDEN bit.
NVIC_InitType NVIC_InitStructure;
/* Enable the PVD Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = PVD_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Configure the PVD Level to 2.4V ,from 2V ~ 4.8V,one step mean add 200mv*/
PWR_PVDLevelConfig(PWR_PVD_LEVEL_2V4);
/* Enable the PVD Output */
PWR_PvdEnable(ENABLE);
The threshold levels map one to one to the PLS encoding in the user manual, so for another voltage just change the macro.
4. Clear the pending bit in the interrupt service function. After confirming line 7 is set, print a hint and clear the flag so the interrupt is not entered repeatedly.
void PVD_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_LINE7) != RESET)
{
log_info("\r\n Enter PVD interrupt \r\n");
/* Clear the Key Button EXTI line pending bit */
EXTI_ClrITPendBit(EXTI_LINE7);
}
}
The handler name must match the vector name in the startup file; when porting to event mode this handler is not needed.
Corresponding source files: src/main.c, src/n32g033_it.c, firmware/n32g033_std_periph_driver/inc/n32g033_pwr.h
5.14.3.2 STOP low-power entry and wake-up
Example directory: projects/n32g033_EVAL/examples/PWR/STOP/
Enable the power-management clock and initialize logging→configure the key pin external interrupt as the wake-up source→delay in the main loop then enter STOP mode→the key triggers the interrupt to wake up→after wake-up reconfigure the system clock and keep printing
| Item | Source analysis |
|---|---|
| Function | After a delay in the main loop enter STOP mode, wake up from the PA0 key through the external interrupt, and after wake-up reconfigure the system clock and keep running. |
| Source files | src/main.c contains SetSysClockToHSI and KeyInputExtiInit;src/n32g033_it.c contains EXTI0_6_IRQHandler;inc/main.h defines the key port and pin;readme.txt gives the configuration and test steps;project files are in MDK-ARM/ and EWARM/. |
| Key configuration | Wake-up pin: PA0 key, rising-edge triggered; interrupt channel: EXTI0_6_IRQn with priority 0x01;entry mode: PWR_STOPENTRY_WFI;clock: HSI 64 MHz, log port PA9-115200. |
| Program and data path | main -> RCC_EnableAPBPeriphClk enables the PWR clock -> log_init -> KeyInputExtiInit connects PA0 to external interrupt line 0 -> the loop runs SysTick_Delay_Ms then PWR_EnterSTOPMode enters STOP -> after the key wakes it SetSysClockToHSI reconfigures the clock -> log_init then keeps printing. |
| Main APIs | PWR_EnterSTOPMode, PWR_GetFlagStatus |
| Verification | After burning, on power-up the serial port prints PWR_STOP INIT, then prints STOP ENTRY meaning it entered STOP;after pressing the PA0 key it prints STOP EXIT, meaning it was woken and resumed from where it stopped. |
| Use note | The development environment is KEIL MDK-ARM V5.34.0.0 or IAR EWARM 8.50.1; HSI is off in STOP mode, so the system clock the serial port needs must be reconfigured after wake-up. |
Core-code walkthrough and porting
The example connects the key pin to an external interrupt as the wake-up source, enters STOP after a delay in the main loop, and reconfigures the clock after wake-up to keep running.
Data path: RCC_EnableAPBPeriphClk enables the PWR clock -> log_init initializes logging -> KeyInputExtiInit configures the PA0 external interrupt -> the loop runs SysTick_Delay_Ms -> PWR_EnterSTOPMode enters STOP -> the key wakes it and SetSysClockToHSI reconfigures the clock -> log_init
1. Enable the PWR clock and initialize logging and the wake-up source. Before entering low power, enable the PWR clock, then initialize the serial logging and the key interrupt.
/* Enable PWR Clock */
RCC_EnableAPBPeriphClk(RCC_APB_PERIPH_PWR, ENABLE);
/* Initialize LEDs on n32g033-EVAL board */
log_init();
log_info("\n PWR_STOP INIT ");
/* Initialize Key button Interrupt to wakeUp stop */
KeyInputExtiInit(KEY_INPUT_PORT, KEY_INPUT_PIN);
KEY_INPUT_PORT and KEY_INPUT_PIN are defined in inc/main.h as GPIOA and pin 0; change these two macros to use another pin.
2. Enter STOP after a delay in the main loop and reconfigure the clock on wake-up. Each iteration delays first, prints, then enters STOP; on wake-up it immediately switches the system clock back to HSI and reinitializes logging.
while (1)
{
/* Insert a long delay */
SysTick_Delay_Ms(2000);
log_info("\n STOP ENTRY ");
PWR_EnterSTOPMode(PWR_STOPENTRY_WFI);
SetSysClockToHSI(RCC_SYSCLK_PRES_DIV1);
log_init();
log_info("\n STOP EXIT ");
}
The clock must be reconfigured after wake-up, otherwise the serial baud rate will not match the core frequency and the output will be garbled.
3. Connect the key pin to the external interrupt line and set the priority. Configure the key pin as floating input, trigger external interrupt line 0 on the rising edge with EXTI0_6_IRQn priority 0x01.
/*Configure key EXTI Line to key input Pin*/
GPIO_ConfigEXTILine(GPIOA_PORT_SOURCE, GPIO_PIN_SOURCE0);
/*Configure key EXTI line*/
EXTI_InitStructure.EXTI_Line = EXTI_LINE0;
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 = EXTI0_6_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority = 0x01;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
The combination of external interrupt source and pin number must follow the EXTI mapping in the user manual; the interrupt channel name is fixed in the startup file.
4. Clear the pending bit in the interrupt service function after wake-up. After confirming line 0 is set, clear the flag so the next key press can still wake it up.
void EXTI0_6_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_LINE0) != RESET)
{
/* Clear the Key Button EXTI line pending bit */
EXTI_ClrITPendBit(EXTI_LINE0);
}
}
When switching to event wake-up, the interrupt channel need not be enabled and this handler is not needed.
Corresponding source files: src/main.c, src/n32g033_it.c, firmware/n32g033_std_periph_driver/inc/n32g033_pwr.h
5.14.4 Notes and troubleshooting
| Scenario | Check & action | Source |
|---|---|---|
| PVD threshold and hysteresis | The PWR chapter of the user manual states that the PVD threshold has 15 selectable levels between 2.0 V and 5 V and the voltage hysteresis is ±100 mV; after selecting a level the actual alarm point shifts with the hysteresis. |
User manual |
| PVD filtering | The PWR chapter of the user manual states that PVD supports programmable filtering based on LSI, 1 to 32 cycles, about 30 to 1024 µs, default about 300 µs; the filter count value is related to the LSI frequency. |
User manual |
| Prerequisite for entering STOP | The PWR chapter of the user manual states that SCB_SCR.SLEEPDEEP=1 must be set before entering STOP mode; an ongoing FLASH or APB access delays entry until the access completes. |
User manual |
| Peripherals in STOP mode | The PWR chapter of the user manual states that in STOP mode HSI is off and LSI is on, and SRAM and register content are retained; ADC should be turned off before entering STOP to avoid extra power. |
User manual |
| EXTI wake-up source | The PWR chapter of the user manual states that any interrupt or event through EXTI can wake STOP and all GPIOs can be configured to EXTI0 to EXTI6; key wake-up requires the pin to be connected to the matching external interrupt line. |
User manual |
| PWR_CTRL2 write protection | The PWR chapter of the user manual states that PWR_CTRL2 has write protection; before modifying it write the 32-bit key 0x5710_3616 then write the actual value; the driver completes this unlock through the write-protection enable function. |
User manual |
| DBG_CTRL access condition | The PWR chapter of the user manual states that DBG_CTRL can only be reset by POR/PDR and software can write it only after a debugger is connected; configuring the debug peripheral stop function must be done in a debug session. |
User manual |
Errata sheet V1.0.0 (2025.9.25) covers revision A silicon and lists no PWR entries.