OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 15753|回复: 33

STM32 可编程电压监测器(PVD)

[复制链接]

48

主题

537

帖子

2

精华

金牌会员

Rank: 6Rank: 6

积分
1367
金钱
1367
注册时间
2014-2-13
在线时间
169 小时
发表于 2014-9-16 11:16:01 | 显示全部楼层 |阅读模式
   1)PVD = Programmable Votage Detector 可编程电压监测器   它的作用是监视供电电压,在供电电压下降到给定的阀值以下时,产生一个中断,通知软件做紧急处理。在给出表格的上半部分就是可编程的监视阀值数据。当供电电压又恢复到给定的阀值以上时,也会产生一个中断,通知软件供电恢复。供电下降的阀值与供电上升的PVD阀值有一个固定的差值,这就是表中的VPVDhyst(PVD迟滞)这个参数,通过列出的PVD阀值数据可以看到这个差别。引入这个差值的目的是为了防止电压在阀值上下小幅抖动,而频繁地产生中断。  
    2)POR = Power On Reset 上电复位;PDR = Power Down Reset 掉电复位。  OR的功能是在VDD电压由低向高上升越过规定的阀值之前,保持芯片复位,当越过这个阀值后的一小段时间后(图中的"滞后时间"或表中的"复位迟滞"),结束复位并取复位向量,开始执行指令。这个阀值就是表中倒数第4行(min=1.8,typ=1.88,max=1.96)。  OR的功能是在VDD电压由高向低下降越过规定的阀值后,将在芯片内部产生复位,这个阀值就是表中倒数第3行(min=1.84,typ=1.92,max=2.0)。     3)可以看到POR比PDR大了0.04V,这就是表中倒数第2行,VPDRhyst(PDR迟滞)=40mV。  
    4)从上面的第2张图可以看到,当VDD上升越过POR阀值时,内部并不马上结束复位,而是等待一小段时间(Reset temporization),这就是表中的最后一行TRSTTEMPO,它的典型数值是2.5ms。  这个滞后时间是为了等待供电电压能够升高到最低可靠工作电压以上,我们看到POR阀值最小只有1.8V,最大也只有1.96V,都低于数据手册中给出的最低可靠工作电压2.0V,所以这个滞后时间是十分必要的,如果供电电压上升缓慢,尤其是从1.8V升到2.0V以上超过1~2.5ms,则很可能造成上电复位后MCU不能正常工作的情况。   
    STM32内部自带PVD功能,用于对MCU供电电压VDD进行监控。通过电源控制寄存器中的PLS[2:0]位可以用来设定监控电压的阀值,通过对外部 电压进行比较来监控电源。当条件触发,需要系统进入特别保护状态,执行紧急关闭任务:对系统的一些数据保存起来,同时对外设进行相应的保护操作。  操作流程:  
    1)、系统启动后启动PVD,并开启相应的中断。  
    WR_PVDLevelConfig(PWR_PVDLevel_2V8); // 设定监控阀值  
    WR_PVDCmd(ENABLE); // 使能PVD  
    EXTI_StructInit(&EXTI_InitStructure);  
    EXTI_InitStructure.EXTI_Line = EXTI_Line16; // PVD连接到中断线16上  
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //使用中断模式  
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Raising;//电压低于阀值时产生中断  
    EXTI_InitStructure.EXTI_LineCmd = ENABLE; // 使能中断线  
    EXTI_Init(&EXTI_InitStructure); // 初始  
    EXTI_InitStructure.EXTI_Trigger的赋值可选项:  
    EXTI_Trigger_Rising---表示电压从高下降到低于设定阀值时产生中断;  
    EXTI_Trigger_Falling---表示电压从低上升到高于设定阀值时产生中断;  
    EXTI_Trigger_Rising_Falling---表示电压上升或下降越过设定阀值时都产生中断。  
2)、当工作电压低于设定阀值时,将产生PVD中断,在中断程序中进行相应的处理:  
void PVD_IRQHandler(void)
{  
    EXTI_ClearITPendingBit(EXTI_Line16);  
    …… // 用户添加紧急处理代码处  
}
-----------------------------------------------------------------------------------搬运-------------------------------------------------------------------------------------------
亲测:
[mw_shl_code=c,true]u32 num = 0; void PWR_PVD_Init(void) { NVIC_InitTypeDef NVIC_InitStructure; EXTI_InitTypeDef EXTI_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);//使能PWR时钟 NVIC_InitStructure.NVIC_IRQChannel = PVD_IRQn; //使能PVD所在的外部中断通道 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级1 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子优先级0 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道 NVIC_Init(&NVIC_InitStructure); EXTI_StructInit(&EXTI_InitStructure); EXTI_InitStructure.EXTI_Line = EXTI_Line16; //PVD连接到中断线16上 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //使用中断模式 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //电压低于阀值时产生中断 EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能中断线 EXTI_Init(&EXTI_InitStructure); //初始 PWR_PVDLevelConfig(PWR_PVDLevel_2V8);//设定监控阀值 PWR_PVDCmd(ENABLE);//使能PVD } void PVD_IRQHandler(void) { EXTI_ClearITPendingBit(EXTI_Line16);//清中断 num = BKP_ReadBackupRegister(BKP_DR10); num++; //用户添加紧急处理代码处 RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);//使能PWR和BKP外设时钟 PWR_BackupAccessCmd(ENABLE);//使能后备寄存器访问 BKP_WriteBackupRegister(BKP_DR10, (u8)num);//启动界面 }[/mw_shl_code]




正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

37

帖子

0

精华

初级会员

Rank: 2

积分
167
金钱
167
注册时间
2014-6-6
在线时间
22 小时
发表于 2016-1-8 08:02:07 | 显示全部楼层
回复 支持 1 反对 0

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2014-9-16 12:26:52 | 显示全部楼层
谢谢分享...
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

120

主题

7878

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12012
金钱
12012
注册时间
2013-9-10
在线时间
427 小时
发表于 2014-9-16 13:08:17 | 显示全部楼层
不错,谢谢分享!!!
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

81

主题

185

帖子

0

精华

高级会员

Rank: 4

积分
534
金钱
534
注册时间
2013-7-4
在线时间
13 小时
发表于 2014-10-9 13:30:55 | 显示全部楼层
EXTI_Trigger_Rising---表示电压从高下降到低于设定阀值时产生中断;  
    EXTI_Trigger_Falling---表示电压从低上升到高于设定阀值时产生中断;
这边没有写反么?
回复 支持 反对

使用道具 举报

48

主题

537

帖子

2

精华

金牌会员

Rank: 6Rank: 6

积分
1367
金钱
1367
注册时间
2014-2-13
在线时间
169 小时
 楼主| 发表于 2014-10-9 14:36:24 | 显示全部楼层
回复【4楼】jimmjimm:
---------------------------------
没反,自己测试。
回复 支持 反对

使用道具 举报

48

主题

537

帖子

2

精华

金牌会员

Rank: 6Rank: 6

积分
1367
金钱
1367
注册时间
2014-2-13
在线时间
169 小时
 楼主| 发表于 2015-3-16 10:31:27 | 显示全部楼层
再补点东西:
掉电中断里能存多少数据,能成多长时间一直是我比较关心的问题,在这里我测试了一下,也提供了一个简单的测试方法,可以粗略的获知。

1、测试RTC后备存储器存数据的速度
[mw_shl_code=c,true]void PVD_IRQHandler(void) { EXTI_ClearITPendingBit(EXTI_Line16);//清中断 vTaskEndScheduler();//关闭调度器 RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR , ENABLE);//使能PWR和BKP外设时钟 PWR_BackupAccessCmd(ENABLE);//使能后备寄存器访问 while(1) { power_time++; RTC_WriteBackupRegister(RTC_BKP_DR14, power_time); } }[/mw_shl_code]

重上电之后,power_time = 171534,也就是说在2.8V掉到2V的时间内能读写171534次那么多,当然这个跟你设计的电路有绝对的关系,这个就根据具体自己的情况去测试吧。(事实证明RTC后备存储器的读写速度是很快的

2、测试掉电的时间
[mw_shl_code=c,true]void PVD_IRQHandler(void) { EXTI_ClearITPendingBit(EXTI_Line16);//清中断 vTaskEndScheduler();//关闭调度器 RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR , ENABLE);//使能PWR和BKP外设时钟 PWR_BackupAccessCmd(ENABLE);//使能后备寄存器访问 while(1) { power_time++; RTC_WriteBackupRegister(RTC_BKP_DR14, power_time); Dellayus(2);//1.2us } }[/mw_shl_code]
重上电之后,power_time = 40496,也就是说在2.8V掉到2V的需要大约33~40ms左右(当然这是我的电路的掉电时间),这个需要具体自行测试。

注意:这里测试的是STM32F207的RTC,用这个存储一些应急数据还是足够的,不建议用FLASH存数据,因为FLASH读写操作需要高压,不确定2~2.8V操作是否稳定,但是STM32手册上说单片机的工作电压到2V还是可以工作的。


[mw_shl_code=c,true]/******************************************************************************* * 函数名 : Dellayu * 描述 : 延时函数(局部使用),调用一次延时的时间: * 72M下是1us,120M下是0.6us * 参数 : usec * 返回值 : 无 *******************************************************************************/ __asm int Dellayu(u32 usec) { ALIGN PUSH.W {r1} //2时钟周期 MOV r1,#18 //1时钟周期 MUL r0,r1 //1时钟周期 SUB r0,#3 //1时钟周期 loop SUBS r0,#1 //1时钟周期 BNE loop //如果跳转则为3个周期,不跳则只有1个周期 POP {r1} //2时钟周期 BX lr //3个时钟周期 //总共所用周期为(usec*4)-4,此处减4主要用于抵消调用此函数的消耗时钟周期(传参1时钟,BLX跳转3时钟) }[/mw_shl_code]


回复 支持 反对

使用道具 举报

8

主题

33

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
414
金钱
414
注册时间
2014-11-15
在线时间
75 小时
发表于 2015-7-9 14:02:11 | 显示全部楼层
掉电测试出来是us级的怎么破···
在你旁边看到的黄昏 美得让人窒息 如此美丽 谨献给我即将逝去的大学四年 fq_2015_2_9
回复 支持 反对

使用道具 举报

48

主题

537

帖子

2

精华

金牌会员

Rank: 6Rank: 6

积分
1367
金钱
1367
注册时间
2014-2-13
在线时间
169 小时
 楼主| 发表于 2015-7-9 14:25:30 | 显示全部楼层
回复【7楼】番茄君:
---------------------------------
加大电容,掉电时间会延长。
回复 支持 反对

使用道具 举报

头像被屏蔽

65

主题

277

帖子

0

精华

高级会员

Rank: 4

积分
674
金钱
674
注册时间
2013-8-11
在线时间
29 小时
发表于 2015-7-11 15:59:41 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

48

主题

537

帖子

2

精华

金牌会员

Rank: 6Rank: 6

积分
1367
金钱
1367
注册时间
2014-2-13
在线时间
169 小时
 楼主| 发表于 2015-7-13 08:46:48 | 显示全部楼层
回复【9楼】z1234zz:
---------------------------------
不客气,谢谢支持
回复 支持 反对

使用道具 举报

1

主题

8

帖子

0

精华

新手上路

积分
21
金钱
21
注册时间
2016-5-7
在线时间
3 小时
发表于 2016-5-13 22:09:13 | 显示全部楼层
能把程序发给我吗,谢谢,拜托
回复 支持 反对

使用道具 举报

48

主题

537

帖子

2

精华

金牌会员

Rank: 6Rank: 6

积分
1367
金钱
1367
注册时间
2014-2-13
在线时间
169 小时
 楼主| 发表于 2016-5-14 08:24:23 | 显示全部楼层
lizi 发表于 2016-5-13 22:09
能把程序发给我吗,谢谢,拜托

就一个中断配置和中断函数就够了啊
回复 支持 反对

使用道具 举报

4

主题

102

帖子

0

精华

高级会员

Rank: 4

积分
900
金钱
900
注册时间
2013-8-28
在线时间
114 小时
发表于 2016-5-14 10:36:25 | 显示全部楼层
谢谢分享
回复 支持 反对

使用道具 举报

0

主题

5

帖子

0

精华

初级会员

Rank: 2

积分
79
金钱
79
注册时间
2015-1-3
在线时间
10 小时
发表于 2016-5-19 11:43:08 | 显示全部楼层
感谢楼主分享
回复 支持 反对

使用道具 举报

0

主题

29

帖子

0

精华

高级会员

Rank: 4

积分
672
金钱
672
注册时间
2012-2-24
在线时间
226 小时
发表于 2016-5-19 21:47:40 来自手机 | 显示全部楼层
谢谢分享!
回复 支持 反对

使用道具 举报

11

主题

200

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1154
金钱
1154
注册时间
2014-11-9
在线时间
228 小时
发表于 2016-6-7 11:43:38 | 显示全部楼层
楼主好人,好贴顶起
回复 支持 反对

使用道具 举报

0

主题

10

帖子

0

精华

初级会员

Rank: 2

积分
99
金钱
99
注册时间
2016-2-21
在线时间
20 小时
发表于 2016-7-9 10:48:50 | 显示全部楼层
谢谢分享,很有用
回复 支持 反对

使用道具 举报

1

主题

7

帖子

0

精华

新手入门

积分
8
金钱
8
注册时间
2016-7-9
在线时间
0 小时
发表于 2016-7-9 11:08:06 | 显示全部楼层

我为什么发表不了帖子
回复 支持 反对

使用道具 举报

12

主题

66

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
424
金钱
424
注册时间
2016-6-12
在线时间
93 小时
发表于 2016-8-22 10:33:46 | 显示全部楼层
MARK下!~~
回复 支持 反对

使用道具 举报

6

主题

45

帖子

0

精华

初级会员

Rank: 2

积分
175
金钱
175
注册时间
2016-5-25
在线时间
29 小时
发表于 2016-11-17 09:45:14 | 显示全部楼层
为啥我用这个就是进不去中断呢?
<a target="_blank" href="http://wpa.qq.com/msgrd?v=3&uin=10984466&site=qq&menu=y
回复 支持 反对

使用道具 举报

6

主题

45

帖子

0

精华

初级会员

Rank: 2

积分
175
金钱
175
注册时间
2016-5-25
在线时间
29 小时
发表于 2016-11-17 09:45:53 | 显示全部楼层
紧急处理那里我加了一个串口发送AA的函数,但是助手什么也收不到啊
<a target="_blank" href="http://wpa.qq.com/msgrd?v=3&uin=10984466&site=qq&menu=y
回复 支持 反对

使用道具 举报

48

主题

537

帖子

2

精华

金牌会员

Rank: 6Rank: 6

积分
1367
金钱
1367
注册时间
2014-2-13
在线时间
169 小时
 楼主| 发表于 2016-11-20 12:51:40 | 显示全部楼层
暖走 发表于 2016-11-17 09:45
紧急处理那里我加了一个串口发送AA的函数,但是助手什么也收不到啊

紧急处理一般只是写寄存器是有原因的,1、掉电时间短;2、此时电压比较低。
printf打印一般都是ms级很耗时间,如果你的电源加的电容不够大,掉电的时间会更短。
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
19
金钱
19
注册时间
2018-2-8
在线时间
2 小时
发表于 2018-2-8 22:31:40 | 显示全部楼层
为什么我在战舰板的跑马灯测试代码中加了这段代码后,只能进掉电中断,无法进上电中断?(掉电是LED0会闪一下,但上电时LED0不亮)

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"

void PWR_PVD_Init(void)
{   
    NVIC_InitTypeDef NVIC_InitStructure;
    EXTI_InitTypeDef EXTI_InitStructure;
     
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);//??PWR??

    NVIC_InitStructure.NVIC_IRQChannel = PVD_IRQn;           //??PVD?????????
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//?????1
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;       //????0
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;          //????????
    NVIC_Init(&NVIC_InitStructure);
     
    EXTI_StructInit(&EXTI_InitStructure);
    EXTI_InitStructure.EXTI_Line = EXTI_Line16;             //PVD??????16?
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;     //??????
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;  //???????????
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;               //?????
    EXTI_Init(&EXTI_InitStructure);                         //??
     
    PWR_PVDLevelConfig(PWR_PVDLevel_2V8);//??????
    PWR_PVDCmd(ENABLE);//??PVD     
}

void PVD_IRQHandler(void)
{
        EXTI_ClearITPendingBit(EXTI_Line16);//clear bit;
        if(PWR_GetFlagStatus(PWR_FLAG_PVDO))
        {
            LED_Init();                          //3õê¼»ˉóëLEDᬽóμÄó2¼t½ó¿ú
            LED0 = 0;
        }
}
  
/************************************************
ALIENTEKÕ½½¢STM32¿a·¢°åêμÑé1
ÅüÂíμÆêμÑé
¼¼êõÖ§3Ö£owww.openedv.com
ìÔ±|μêÆì£ohttp://eboard.taobao.com
1Ø×¢Î¢DÅ1«Öúƽì¨Î¢DÅoÅ£o"ÕyμãÔ-×ó"£¬Ãa·Ñ»ñè¡STM32×êáÏ¡£
1ãÖYêDDÇòíμç×ó¿Æ¼¼óDÏT1«Ë¾  
×÷ÕߣoÕyμãÔ-×ó @ALIENTEK
************************************************/

int main(void)
{       
        delay_init();            //Ñóê±oˉêy3õê¼»ˉ
        //LED_Init();                          //3õê¼»ˉóëLEDᬽóμÄó2¼t½ó¿ú
        //delay_ms(5000);
   
    PWR_PVD_Init();
    while(1);
   
        while(1)
        {
                LED0=0;
                LED1=1;
                delay_ms(1000);         //Ñóê±300ms
                LED0=1;
                LED1=0;
                delay_ms(1000);        //Ñóê±300ms
        }
}
回复 支持 反对

使用道具 举报

26

主题

355

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1770
金钱
1770
注册时间
2017-4-1
在线时间
432 小时
发表于 2018-7-10 11:46:35 | 显示全部楼层
请问电容要达到多大才行,我用示波器测量2.9V衰减到2.0V有17ms时间,但是没有进PVD中断,这是不是不太正常
回复 支持 反对

使用道具 举报

26

主题

355

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1770
金钱
1770
注册时间
2017-4-1
在线时间
432 小时
发表于 2018-7-10 13:05:35 | 显示全部楼层
我换了一个板子就可以,但是两个板子的衰减时间差不多2都是0ms,这就有点奇怪了,继续探索中
回复 支持 反对

使用道具 举报

26

主题

355

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1770
金钱
1770
注册时间
2017-4-1
在线时间
432 小时
发表于 2018-7-10 13:06:22 | 显示全部楼层
陈皮皮 发表于 2018-7-10 13:05
我换了一个板子就可以,但是两个板子的衰减时间差不多2都是0ms,这就有点奇怪了,继续探索中

20ms,打错了
回复 支持 反对

使用道具 举报

26

主题

355

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1770
金钱
1770
注册时间
2017-4-1
在线时间
432 小时
发表于 2018-7-10 15:00:31 | 显示全部楼层
陈皮皮 发表于 2018-7-10 11:46
请问电容要达到多大才行,我用示波器测量2.9V衰减到2.0V有17ms时间,但是没有进PVD中断,这是不是不太正常

不好意思啊,找到原因了,我有一块板子VBAT供电掉了,导致后备寄存器中的值清零了
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
14
金钱
14
注册时间
2018-8-1
在线时间
1 小时
发表于 2018-8-1 14:20:03 | 显示全部楼层
小白新手,请问楼主PWR和BKP时钟在这里有什么作用
回复 支持 反对

使用道具 举报

2

主题

7

帖子

0

精华

新手上路

积分
32
金钱
32
注册时间
2018-6-7
在线时间
9 小时
发表于 2018-9-27 14:50:04 | 显示全部楼层
RCC_APB1Periph_BKP请问楼主这个的值是多少,库函数上并没有定义这个
回复 支持 反对

使用道具 举报

10

主题

32

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2011-10-26
在线时间
10 小时
发表于 2018-11-26 11:30:12 | 显示全部楼层
感谢分享,mark一下
回复 支持 反对

使用道具 举报

0

主题

22

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
223
金钱
223
注册时间
2018-6-2
在线时间
65 小时
发表于 2018-11-26 12:36:14 | 显示全部楼层
mark一下 备用
回复 支持 反对

使用道具 举报

1

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
165
金钱
165
注册时间
2018-1-18
在线时间
22 小时
发表于 2019-5-29 13:30:27 | 显示全部楼层
谢谢分享
回复 支持 反对

使用道具 举报

2

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2017-5-24
在线时间
13 小时
发表于 2022-1-26 21:10:24 | 显示全部楼层
感谢分享!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-20 18:31

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表