前言:stm32系列提供了可编程电压检测器PVD,它是实时检测VDD的电压,当检测到电压低于或者高于PVD设置的阈值时,会想内核产生一个PVD中断(EXTI线中断)以使内核在复位前进行紧急处理。该电压阈值可通过PWR_CSR设置。
PVD可配置8个等级:
代码设计:
#include "stm32f10x.h"
#include "stdio.h"
static void EXTI_Configuration(void);
static void PVD_NVIC_Configuration(void);
static void USART1_Config(void);
static void Delay(__IO u32 nCount);
int main(void)
{
USART1_Config();//使用串口1来打印调试信息
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); //使能PVD电压检测模块的时钟
//通过执行下面两个中断配置函数后,当VDD电压高于或者低于阈值时,就会进入PVD_IRQHandler中断
EXTI_Configuration();//配置EXTI_Line16外部中断
PVD_NVIC_Configuration();//PVD中断优先级
PWR_PVDLevelConfig(PWR_PVDLevel_2V9);//设置PVD阈值
PWR_PVDCmd(ENABLE);//使能PVD电压检测
while(1)
{
Delay(0xfffff);
printf("STM32正常工作中...rn");
//去掉上面两个中断配置函数,也可以在while循环里不断查询PWR状态来判断VDD电压是否高于或低于阈值,如下
#if 0
if(PWR_GetFlagStatus(PWR_FLAG_PVDO)){
printf("电压低于阈值.rn");
}else{
printf("电压高于阈值.rn");
}
#endif
}
}
void EXTI_Configuration(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_DeInit();
EXTI_StructInit(&EXTI_InitStructure);
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_Init(&EXTI_InitStructure);
}
void PVD_NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = PVD_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void USART1_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
//配置串口1(USART1)时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
//配置串口1(USART1 Tx (PA.09))
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//配置串口1 USART1 Rx (PA.10)
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//串口1模式(USART1 mode)配置
USART_InitStructure.USART_BaudRate = 9600;//一般设置为9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No ;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE); //使能串口
}
int fputc(int ch, FILE *f)//重写标准库的fputc函数
{
//将Printf内容发往串口
USART_SendData(USART1, (unsigned char) ch);
while( USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET);
return (ch);
}
void Delay(__IO u32 nCount) //简单的延时函数
{
for(; nCount != 0; nCount--);
}
在stm32f10x_it.c文件加入:
void PVD_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_Line16) != RESET)
{
if(PWR_GetFlagStatus(PWR_FLAG_PVDO)==0) //高于阈值
{
printf("进入PVD中断,电压高于阈值rn");
}
else //低于阈值
{
printf("进入PVD中断,电压低于阈值rn");
}
EXTI_ClearITPendingBit(EXTI_Line16);
}
}
代码附带了不少注释,相信不难理解。编译下载到板子后,还需要一个可调电源来改变芯片的供电电压,当电压低于或者高于阈值的时候,就会进入PVD_IRQHandler中断,在PC端串口上位机可接受到进入中断打印的信息。
只要电压超过2.0v芯片就能正常工作,不是低于阈值就不能工作。所以在实际运用中,如果是用电池给芯片供电,当电池电量不足时,电池的供电电压就会下降,下降到低于阈值时就会触发PVD中断,那么这时候需要进行数据备份处理或者进行低电量提醒。
如果直接切断电源,进入中断只能维持很短很短的时间,连一句打印信息也无法完整输出。解决这个问题,需要在电源输入点加大电容,当掉电的时候由电容提供电源维持芯片运行一段时候,以做紧急数据保存。所选用电容的参数影响掉电后芯片维持运行的时间,根据掉电中断处理所需的时间长短来选用电容。
上一篇:stm32之备份寄存器(BKP)应用(侵入检测中断)
下一篇:stm32之电源管理(实现低功耗)
推荐阅读最新更新时间:2024-11-12 03:32
设计资源 培训 开发板 精华推荐
- LT3756IMSE-1 94% 效率 30W 白光 LED 前照灯驱动器的典型应用电路
- LT3088IST 宽安全工作区电源的典型应用
- DC1627A-A,旨在显示 LTC4226CUD-1 宽工作范围双通道热插拔控制器的热插拔功能的演示电路
- 使用 ROHM Semiconductor 的 BD48K42G-TL 的参考设计
- L7805C 具有短路保护的高输出电流的典型应用
- 用于电池充电器的 24.6W、8.2V 交流转直流单输出电源
- 带有 PTN5110 USB PD TCPC PHY 的 Type-C 适配器的典型应用
- 使用 Analog Devices 的 LT1584CT-3.6 的参考设计
- 使用 Analog Devices 的 LTC6262HMS8 的参考设计
- 使用 ROHM Semiconductor 的 BD49L31G-TL 的参考设计