一、PVD功能介绍
PY32F003F18有一个PVD可编程电压检测模块。
"PVD可编程电压检测"可以用来检测"VCC引脚电压",也可以检测"PB7引脚电压";
当使用VCC作为检测源时,VCC > "PVDT[2:0]设置的值" 或者 VCC < "PVDT[2:0]设置的值" 时,"EXTI line 16"会产生"上升/下降沿中断"
当使用PB07引脚作为检测源时,Vpb07 > VREFINT 或者 Vpb07 < VREFINT 时,"EXTI line 16"会产生"上升/下降沿中断"
VREFINT固定值为1.2V
"电源控制寄存器2(PWR_CR2)"中的SRCSEL=0,VCC电压会与"PVDT[2:0]设置的值(检测阈值)"进行比较;测试时,通过调节VCC电压,可发现"EXTI line 16"会产生"上升/下降沿中断";
"电源控制寄存器2(PWR_CR2)"中的SRCSEL=1,PB7上的电压会在内部与VREFINT进行比较
PB7作为检测源,PB7上的电压会在内部与VREFINT进行比较,因此,设置"检测阈值PVDT[2:0]"无效。
二、测试程序
- #include "PVD.h"
- #include "LED.h"
-
- /*
- "PVD可编程电压检测"可以用来检测"VCC引脚电压",也可以检测"PB7引脚电压";
- 当使用VCC作为检测源时,VCC > "PVDT[2:0]设置的值" 或者 VCC < "PVDT[2:0]设置的值" 时,"EXTI line 16"会产生"上升/下降沿中断"
- 当使用PB07引脚作为检测源时,Vpb07 > VREFINT 或者 Vpb07 < VREFINT 时,"EXTI line 16"会产生"上升/下降沿中断"
- VREFINT固定值为1.2V
-
- "电源控制寄存器2(PWR_CR2)"中的SRCSEL=0,VCC电压会与"PVDT[2:0]设置的值(检测阈值)"进行比较
- 测试时,通过调节VCC电压,可发现"EXTI line 16"会产生"上升/下降沿中断";
-
- "电源控制寄存器2(PWR_CR2)"中的SRCSEL=1,PB7上的电压会在内部与VREFINT进行比较
- PB07作为检测源,PB7上的电压会在内部与VREFINT进行比较,因此,设置"检测阈值PVDT[2:0]"无效
- */
-
- void PVD_Init_With_PB7(void);
- void PVD_Init_With_VCC(void);
-
- //函数功能:使用"PB7引脚"作为"PVD检测源"
- void PVD_Init_With_PB7(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- PWR_PVDTypeDef PWR_PVDStructure;
-
- PB7引脚初始化为模拟输入口开始//
- __HAL_RCC_GPIOB_CLK_ENABLE();//使能GPIOB时钟
- GPIO_InitStructure.Pin = GPIO_PIN_7;
- GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;
- GPIO_InitStructure.Pull = GPIO_PULLUP;
- HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
- PB7引脚初始化为模拟输入口结束//
-
- __HAL_RCC_PWR_CLK_ENABLE(); //PWR时钟使能
-
- PWR_PVDStructure.PVDSource=PWR_PVD_SOURCE_PB07; //PVD检测为PB07
- PWR_PVDStructure.Mode=PWR_PVD_MODE_IT_RISING_FALLING; //PVD配置为上升沿和下降沿中断
- PWR_PVDStructure.PVDFilter=PWR_PVD_FILTER_NONE; //无"数字滤波功能"
- PWR_PVDStructure.PVDLevel=PWR_PVDLEVEL_0;
- //PB07作为检测源,PB7上的电压会在内部与VREFINT进行比较,因此,设置PVDT[2:0]无效
- //VCC作为检测源,VCC电压会与"PVDT[2:0]设置的值"进行比较
- HAL_PWR_ConfigPVD(&PWR_PVDStructure); //PVD初始化
- //PWR_PVDStructure->PVDLevel=PWR_PVDLEVEL_0,电压上升沿检测阈值大约为1.8V;
- //PWR_PVDStructure->PVDLevel=PWR_PVDLEVEL_1,电压上升沿检测阈值大约为2.0V;
- //PWR_PVDStructure->PVDLevel=PWR_PVDLEVEL_2,电压上升沿检测阈值大约为2.2V;
- //PWR_PVDStructure->PVDLevel=PWR_PVDLEVEL_3,电压上升沿检测阈值大约为2.4V;
- //PWR_PVDStructure->PVDLevel=PWR_PVDLEVEL_4,电压上升沿检测阈值大约为2.6V;
- //PWR_PVDStructure->PVDLevel=PWR_PVDLEVEL_5,电压上升沿检测阈值大约为2.8V;
- //PWR_PVDStructure->PVDLevel=PWR_PVDLEVEL_6,电压上升沿检测阈值大约为3.0V;
- //PWR_PVDStructure->PVDLevel=PWR_PVDLEVEL_7,电压上升沿检测阈值大约为3.2V;
-
- //PWR_PVDStructure->PVDFilter=PWR_PVD_FILTER_NONE,无"数字滤波功能"
- //PWR_PVDStructure->PVDFilter=PWR_PVD_FILTER_1CLOCK,滤波时间大约为30us
- //PWR_PVDStructure->PVDFilter=PWR_PVD_FILTER_2CLOCK,滤波时间大约为60us
- //PWR_PVDStructure->PVDFilter=PWR_PVD_FILTER_4CLOCK,滤波时间大约为120us
- //PWR_PVDStructure->PVDFilter=PWR_PVD_FILTER_16CLOCK,滤波时间大约为480us
- //PWR_PVDStructure->PVDFilter=PWR_PVD_FILTER_64CLOCK,滤波时间大约为1.92ms
- //PWR_PVDStructure->PVDFilter=PWR_PVD_FILTER_128CLOCK,滤波时间大约为3.8ms
- //PWR_PVDStructure->PVDFilter=PWR_PVD_FILTER_1024CLOCK,滤波时间大约为30.7ms
-
- //PWR_PVDStructure->PVDSource=PWR_PVD_SOURCE_PB07,检测PB7引脚电压
- //PWR_PVDStructure->PVDSource=PWR_PVD_SOURCE_VCC,检测VCC引脚电压
-
- //PWR_PVDStructure->Mode=PWR_PVD_MODE_IT_RISING,PVD配置为上升沿中断
- //PWR_PVDStructure->Mode=PWR_PVD_MODE_IT_FALLING,PVD配置为下降沿中断
- //PWR_PVDStructure->Mode=PWR_PVD_MODE_IT_RISING_FALLING,PVD配置为上升沿和下降沿中断
- //PWR_PVDStructure->Mode=PWR_PVD_MODE_EVENT_RISING,PVD配置为上升沿事件唤醒
- //PWR_PVDStructure->Mode=PWR_PVD_MODE_EVENT_FALLING,PVD配置为下降沿事件唤醒
- //PWR_PVDStructure->Mode=PWR_PVD_MODE_EVENT_RISING_FALLING,PVD配置为上升沿和下降沿事件唤醒
-
- HAL_NVIC_EnableIRQ(PVD_IRQn);
- //使能"PVD中断源"产生中断
-
- HAL_PWR_EnablePVD();//使能PVD电压检测
- }
-
- //函数功能:使用"VCC引脚"作为"PVD检测源"
- //调节VCC电压,测试正常
- void PVD_Init_With_VCC(void)
- {
- PWR_PVDTypeDef PWR_PVDStructure;
-
- __HAL_RCC_PWR_CLK_ENABLE(); //PWR时钟使能
-
- PWR_PVDStructure.PVDSource=PWR_PVD_SOURCE_VCC; //PVD检测为VCC引脚
- PWR_PVDStructure.Mode=PWR_PVD_MODE_IT_RISING_FALLING; //PVD配置为上升沿和下降沿中断
- PWR_PVDStructure.PVDFilter=PWR_PVD_FILTER_NONE; //无"数字滤波功能"
- PWR_PVDStructure.PVDLevel=PWR_PVDLEVEL_7;
- //电压上升沿检测阈值大约为3.2V;
- //VCC作为检测源,VCC电压会与"PVDT[2:0]设置的值"进行比较
- //PB07作为检测源,PB7上的电压会在内部与VREFINT进行比较,因此,设置PVDT[2:0]无效
- HAL_PWR_ConfigPVD(&PWR_PVDStructure); //PVD初始化
- //PWR_PVDStructure->PVDLevel=PWR_PVDLEVEL_0,电压上升沿检测阈值大约为1.8V;
- //PWR_PVDStructure->PVDLevel=PWR_PVDLEVEL_1,电压上升沿检测阈值大约为2.0V;
- //PWR_PVDStructure->PVDLevel=PWR_PVDLEVEL_2,电压上升沿检测阈值大约为2.2V;
- //PWR_PVDStructure->PVDLevel=PWR_PVDLEVEL_3,电压上升沿检测阈值大约为2.4V;
- //PWR_PVDStructure->PVDLevel=PWR_PVDLEVEL_4,电压上升沿检测阈值大约为2.6V;
- //PWR_PVDStructure->PVDLevel=PWR_PVDLEVEL_5,电压上升沿检测阈值大约为2.8V;
- //PWR_PVDStructure->PVDLevel=PWR_PVDLEVEL_6,电压上升沿检测阈值大约为3.0V;
- //PWR_PVDStructure->PVDLevel=PWR_PVDLEVEL_7,电压上升沿检测阈值大约为3.2V;
-
- //PWR_PVDStructure->PVDFilter=PWR_PVD_FILTER_NONE,无"数字滤波功能"
- //PWR_PVDStructure->PVDFilter=PWR_PVD_FILTER_1CLOCK,滤波时间大约为30us
- //PWR_PVDStructure->PVDFilter=PWR_PVD_FILTER_2CLOCK,滤波时间大约为60us
- //PWR_PVDStructure->PVDFilter=PWR_PVD_FILTER_4CLOCK,滤波时间大约为120us
- //PWR_PVDStructure->PVDFilter=PWR_PVD_FILTER_16CLOCK,滤波时间大约为480us
- //PWR_PVDStructure->PVDFilter=PWR_PVD_FILTER_64CLOCK,滤波时间大约为1.92ms
- //PWR_PVDStructure->PVDFilter=PWR_PVD_FILTER_128CLOCK,滤波时间大约为3.8ms
- //PWR_PVDStructure->PVDFilter=PWR_PVD_FILTER_1024CLOCK,滤波时间大约为30.7ms
-
- //PWR_PVDStructure->PVDSource=PWR_PVD_SOURCE_PB07,检测PB7引脚电压
- //PWR_PVDStructure->PVDSource=PWR_PVD_SOURCE_VCC,检测VCC引脚电压
-
- //PWR_PVDStructure->Mode=PWR_PVD_MODE_IT_RISING,PVD配置为上升沿中断
- //PWR_PVDStructure->Mode=PWR_PVD_MODE_IT_FALLING,PVD配置为下降沿中断
- //PWR_PVDStructure->Mode=PWR_PVD_MODE_IT_RISING_FALLING,PVD配置为上升沿和下降沿中断
- //PWR_PVDStructure->Mode=PWR_PVD_MODE_EVENT_RISING,PVD配置为上升沿事件唤醒
- //PWR_PVDStructure->Mode=PWR_PVD_MODE_EVENT_FALLING,PVD配置为下降沿事件唤醒
- //PWR_PVDStructure->Mode=PWR_PVD_MODE_EVENT_RISING_FALLING,PVD配置为上升沿和下降沿事件唤醒
-
- HAL_NVIC_EnableIRQ(PVD_IRQn);
- //使能"PVD中断源"产生中断
-
- __HAL_PWR_PVD_EXTI_CLEAR_FLAG();
- //写"挂起寄存器EXTI_PR"中的PR16位,PR16=1表示清除"EXTI line 16上升沿/下降沿/软件触发事件请求"
- //Clear PVD exti pending bit
-
- HAL_PWR_EnablePVD();//使能PVD电压检测
- }
-
- //函数功能:PVD上升沿/下降沿中断服务函数
- //"EXTI line 16"上升/下降沿中断
- void PVD_IRQHandler(void)
- {
- if(__HAL_PWR_PVD_EXTI_GET_FLAG() != 0x0U)
- {//读"挂起寄存器EXTI_PR"中的PR16位,PR16=1表示产生"EXTI line 16上升沿/下降沿/软件触发事件请求"
-
- __HAL_PWR_PVD_EXTI_CLEAR_FLAG();
- //写"挂起寄存器EXTI_PR"中的PR16位,PR16=1表示清除"EXTI line 16上升沿/下降沿/软件触发事件请求"
- //Clear PVD exti pending bit
-
- //HAL_PWR_PVD_Callback函数开始
- if(__HAL_PWR_GET_FLAG(PWR_SR_PVDO))//小于"PVD选择的比较阈值"
- { //(__FLAG__)=PWR_FLAG_PVDO,读"电源状态寄存器PWR_SR"中的PVDO位
- //返回值0,PVD检测结果输出:被检测的VCC或者PB7超出PVD选择的比较阈值
- //返回值1,PVD检测结果输出:被检测的VCC或者PB7低于PVD选择的比较阈值
- // MCU_LED_Off();
- MCU_LED_On();
- }
- else//大于"PVD选择的比较阈值"
- {
- // MCU_LED_On();
- MCU_LED_Off();
- }
- //HAL_PWR_PVD_Callback函数结束
- }
- }
- #include "py32f0xx_hal.h"
- #include "SystemClock.h"
- #include "delay.h"
- #include "LED.h"
- #include "SystemClock.h"
- #include "USART2.h"
- #include "stdio.h" //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
- #include "string.h" //使能strcpy(),strlen(),memset()
- #include "PVD.h"
-
- const char CPU_Reset_REG[]="\r\nCPU reset!\r\n";
- const char CPU_Run_REG[]="\r\nCPU run!\r\n";
- int main(void)
- {
- HSE_Config();
- // HSI_Config();
- // HAL_Init();//systick初始化
- delay_init();
- HAL_Delay(1000);
- USART2_Init(115200);
- //PA0是为USART2_TX,PA1是USART2_RX
- //中断优先级为0x01
- //波特率为115200,数字为8位,停止位为1位,无奇偶校验,允许发送和接收数据,只允许接收中断,并使能串口
- printf("%s",CPU_Reset_REG);
- HAL_Delay(1000);
- printf("%s",CPU_Run_REG);
-
- MCU_LED_Init();
- // PVD_Init_With_PB7();//使用"PB7引脚"作为"PVD检测源"
- PVD_Init_With_VCC(); //使用"VCC引脚"作为"PVD检测源",调节VCC电压,测试正常
- while (1)
- {
- HAL_Delay(500);
- // MCU_LED_Toggle();
- printf("1234567890\r\n");
- }
- }
三、实验结果
"EXTI line 16"会产生"上升/下降沿中断",LED状态会改变。