stm32 PVD programmable voltage monitor

Publisher:平和的心态Latest update time:2017-02-06 Source: eefocusKeywords:stm32  PVD  programmable Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

    PVD (Programmable Votage Detector) is a programmable voltage detector. The STM32 library function manual does not explain this module in detail, but only lists two related functions in the PWM chapter. However, this function will play a greater role in actual projects.

When the voltage is too low, some system data is saved using EEPROM or Flash that will not be lost when power is off, and corresponding protection operations are performed on peripherals. 

 

    The function of PVD is to monitor the power supply voltage. When the power supply voltage drops below a given threshold, an interrupt is generated to notify the software to perform emergency processing. When the power supply voltage returns to above the given threshold, an interrupt is also generated to notify the software that the power supply has been restored. There is a fixed difference between the threshold for power supply drop and the PVD threshold for power supply rise. The purpose of introducing this difference is to prevent the voltage from fluctuating slightly above and below the threshold, which will cause frequent interrupts.

 

    When using STM32, users can use its internal PVD to monitor the voltage of VDD and set the monitored voltage value through the PLS[2:0] bits in the power control register (PWR_CR).

 

    The PLS[2:0] bits are used to select the voltage threshold for the PVD monitoring power supply:

 

                 000:2.2V

                 001:2.3V

                 010:2.4V

                 011:2.5V

                 100:2.6V

                 101:2.7V

                 110:2.8V

                 111:2.9V

 

     The PVDO flag in the power control/status register (PWR_CSR) is used to indicate whether VDD is above or below the voltage threshold set by PVD. This event is connected to the 16th line of the external interrupt. If the interrupt is enabled in the external interrupt register, the event will generate an interrupt. When VDD drops below the PVD threshold and/or when VDD rises above the PVD threshold, a PVD interrupt will be generated according to the rising/falling edge trigger setting of the 16th line of the external interrupt.

 

    So I did an experiment to test the PVD function of stm32. Set the PVD monitoring threshold to 2.8V, use a voltage divider module to divide the 5V voltage through an adjustable resistor to stm32, set an LED to light up in the PVD interrupt, adjust the adjustable resistor size, and verify whether PVD is triggered.


 

    The experimental results are shown in the figure:

 

     stm32-PVD.jpg

 

     When the power supply is only 2.02V, the PVD interrupt is triggered and the LED is lit. However, the chip is always in reset and resets after detecting insufficient voltage.

 

stm32 PVD code:

#include "stm32f10x.h"

void RCC_Configuration(void);
void NVIC_Configuration(void);
void GPIO_Configuration(void);
void EXTI_Configuration(void);
void PVD_Configuration(void);


int main(void)	  
{

	//stm32 initialization		
	RCC_Configuration();
	NVIC_Configuration();		
	EXIT_Configuration();
	GPIO_Configuration();

	GPIO_SetBits(GPIOA,GPIO_Pin_8); 

	PVD_Configuration();

	while(1);
}



void PVD_Configuration(void)
{
	PWR_PVDLevelConfig(PWR_PVDLevel_2V8); //Set monitoring threshold 
	PWR_PVDCmd(ENABLE);	

}


void EXTI_Configuration(void)
{
    EXTI_InitTypeDef EXTI_InitStructure;
 
	EXTI_InitStructure.EXTI_Line = EXTI_Line16;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;			
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //Indicates that an interrupt is generated when the voltage drops from a high voltage to below the set voltage threshold
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;	
	EXTI_Init(&EXTI_InitStructure);		
}



void NVIC_Configuration(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;

#ifdef  VECT_TAB_RAM
	NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else  /* VECT_TAB_FLASH  */
	NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endif

	/* Configure one bit for preemption priority */
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

	NVIC_InitStructure.NVIC_IRQChannel =PVD_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}


void RCC_Configuration(void)
{
	ErrorStatus HSEStartUpStatus;

	// Enable external crystal oscillator
	RCC_HSEConfig(RCC_HSE_ON);
	//Wait for the external crystal to stabilize
	HSEStartUpStatus = RCC_WaitForHSEStartUp();
	//If the external crystal oscillator is started successfully, proceed to the next step
	if (HSEStartUpStatus==SUCCESS)
	{
		//Set HCLK (AHB clock) = SYSCLK
		RCC_HCLKConfig(RCC_SYSCLK_Div1);

		//PCLK1(APB1) = HCLK/2
		RCC_PCLK1Config(RCC_HCLK_Div2);

		//PCLK2(APB2) = HCLK
		RCC_PCLK2Config(RCC_HCLK_Div1);

		//FLASH timing control
		//Recommended value: SYSCLK = 0~24MHz Latency=0
		//        SYSCLK = 24~48MHz  Latency=1
		//        SYSCLK = 48~72MHz  Latency=2
		FLASH_SetLatency(FLASH_Latency_2);
		// Enable FLASH prefetch function
		FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

		//PLL setting SYSCLK/1 * 9 = 8*1*9 = 72MHz
		RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
		//Start PLL
		RCC_PLLCmd(ENABLE);
		//Wait for PLL to stabilize
		while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
		//The system clock SYSCLK comes from the PLL output
		RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
		//Wait for the system clock to stabilize after switching the clock
		while (RCC_GetSYSCLKSource()!=0x08);
	}

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); //Enable PVD clock

}

void GPIO_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	//LED
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
}

//PVD interrupt program
void PVD_IRQHandler(void)
{
	if(PWR_GetFlagStatus(PWR_FLAG_PVDO))     
	{
		GPIO_ResetBits(GPIOA,GPIO_Pin_8);
	}

	EXTI_ClearITPendingBit(EXTI_Line16); //Clear interrupt
}

 

In void EXTI_Configuration(void), for

    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;

Modify the initialization value in according to your needs. The details are as follows:

  •     EXTI_Trigger_Rising --- Indicates that an interrupt is generated when the voltage drops from a high voltage to below the set voltage threshold;

  •     EXTI_Trigger_Falling --- Indicates that the voltage rises from a low voltage to a higher than the set voltage threshold and generates an interrupt;

  •     EXTI_Trigger_Rising_Falling --- Indicates that an interrupt is generated when the voltage drops from a high voltage to below the set voltage threshold, or rises from a low voltage to above the set voltage threshold.


Keywords:stm32  PVD  programmable Reference address:stm32 PVD programmable voltage monitor

Previous article:Stm32 SWD download debug configuration
Next article:stm32 external interrupt nesting [operation register + library function]

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号