rjx 发表于 2017-8-2 10:14:01

用STM32的PVD来做掉电保存数据,但不成功,求帮助(搞定了!)

本帖最后由 rjx 于 2017-8-2 14:22 编辑

想用STM32的PVD功能来实现掉电保存数据,但不成功,请帮我看看是什么原因。当达到设定的阈值时产生中断,此时将数据写入AT24C02,其中24C02的写入是没有问题的,已用其他方式试过。

void pvd_init(void)         //
{      

      EXTI_InitTypeDef EXTI_InitStructure;
      NVIC_InitTypeDef NVIC_InitStructure;      

      /* 开启PVD时钟 */
         RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);      //开启PVD时钟

      /* 设置中断的模式 */         
      EXTI_InitStructure.EXTI_Line=EXTI_Line16;
      EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
      EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising;   //表示电压从高电压下降到低于设定的电压阀值产生中断
      EXTI_InitStructure.EXTI_LineCmd = ENABLE;
      EXTI_Init(&EXTI_InitStructure);
      
      /* 设置NVIC参数 */      
      //NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);               
      NVIC_InitStructure.NVIC_IRQChannel = PVD_IRQn;         //打开PVD中断
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级为0
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;                  //响应优先级为3
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                   //使能
      NVIC_Init(&NVIC_InitStructure);
      
       PWR_PVDCmd(ENABLE);
       PWR_PVDLevelConfig(PWR_PVDLevel_2V9);       // 设定监控阀值            
}


void PVD_IRQHandler()         //PVD中断函数
{
      
      if(PWR_GetFlagStatus(PWR_FLAG_PVDO))
            {
                  
                  AT24CXX_WriteOneByte(0x02,VOLUME_1); //write_eep(0x02,VOLUME_1);         
                  delay_ms(10);               
         }
      EXTI_ClearITPendingBit(EXTI_Line16);//清除EXTI线路挂起位      
}

jiespring 发表于 2017-8-2 11:18:01

我觉得问题出在这里:EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising;    改Falling试试

rjx 发表于 2017-8-2 14:21:31

终于搞定了!根本不用这么复杂,用简单的查询方式就可以了,几条语句就行了,与大家分享:思路非常务实:
1、开PWR时钟-----必须的。
2、使能PVD
3、设置监控电压的阈值,这里设为2.9V.
4、再判断到阈值后,标志位是否置位,如置位,就保存数值到EEPROM.
至于为什么用中断方式失败,原因不清。

int main()
{
   RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);//打开PWR时钟
   PWR_PVDCmd(ENABLE);   //使能PVD
   PWR_PVDLevelConfig(PWR_PVDLevel_2V9);   //设置PVD的探测电压阀值为2.9V。可设置范围:2.2-2.9
   
   while(1)
      {
               if(PWR_GetFlagStatus(PWR_FLAG_PVDO)==SET)
                     {                  
                              AT24CXX_WriteOneByte(0x02,VOLUME_1); //write_eep(0x02,VOLUME_1);         
                              delay_ms(4);               
                     }
      }

}

ywlzh 发表于 2017-8-2 14:38:32

好像ADC中有个窗口看门狗的功能 这个是可以用中断的,如果用这个,不知道与楼主的查询方式能不能达到一样的效果

rjx 发表于 2017-8-2 14:55:44

用ADC来检测电源电压的方式,是完全可以的,我原来在PIC,AVR单片机中一直用此法。改用STM32 后,也一直用ADC的方式,要注意的是采样电压要取自整流滤波后,7805稳压前的大电解上,再用2个电阻分压。滤波大电解的容量不能小于3300U.
最近才研究用STM32的PVD功能,也是可行的,最大的好处是没有外部电路,非常方便。

XYY136 发表于 2017-8-9 22:05:56

请问STM32的PVD有没有具体的引脚,如果没有会不会来不及保存,谢谢

wangyan915205 发表于 2017-8-9 22:37:44

电压检测精度如何,能否作为欠压报警,有待测试!

rjx 发表于 2017-8-10 09:45:29

回楼上2位:
1、PVD没有具体引脚。滤波电容用大些时间是足够的。
2、完全可以做欠压报警用。

fengyunyu 发表于 2017-8-10 09:53:50

rjx 发表于 2017-8-10 09:45
回楼上2位:
1、PVD没有具体引脚。滤波电容用大些时间是足够的。
2、完全可以做欠压报警用。 ...

滤波电容取多大?

fengyunyu 发表于 2018-2-4 16:57:08

rjx 发表于 2017-8-2 14:55
用ADC来检测电源电压的方式,是完全可以的,我原来在PIC,AVR单片机中一直用此法。改用STM32 后,也一直用A ...

大电容,上电时电流大,升压慢,掉电也慢,可能会有复位问题

rjx 发表于 2018-2-13 10:58:50

主滤波电容用3300U,没有发现什么问题。

苹果520 发表于 2018-4-10 16:54:40

rjx 发表于 2018-2-13 10:58
主滤波电容用3300U,没有发现什么问题。

可以贴出这部分电路吗?我的项目上正打算用这部分电路.

rjx 发表于 2018-4-12 14:26:57

本帖最后由 rjx 于 2018-4-12 14:28 编辑

很简单,从整流后取出电压,再用2个电阻分压。见图:

Elex 发表于 2018-4-12 14:30:27

才1个字节的数据不需要外部eeprom,直接保存在OB里面的用户字节里即可

rjx 发表于 2018-4-12 14:36:18

运行中还要保存其他的数据,但也不多,只有7-8个字节。楼上能否详细讲一下关于OB用户字节的问题,我不是太懂。先谢谢了。

擦鞋匠 发表于 2018-4-12 16:03:34

楼主使用循环去检测电压有点浪费CPU的嫌疑。pvd中断完全可以做到。

个人经验:stm32vct6 + keil

不管是使用eeprom还是flash保存数据,在写入数据前都需要先擦除相应的存储器(上电擦除这段存储空间,掉电写入这段存储空间,以节约时间)。因为擦除的时间是很长的,在擦除的这段时间内足以写入上百字节数据(我在pvd中断里写入不低于100字节数据)。

例如:25lc512每擦除一个page(一个page是256字节)的时间典型值是5ms。

Elex 发表于 2018-4-12 23:51:17

rjx 发表于 2018-4-12 14:36
运行中还要保存其他的数据,但也不多,只有7-8个字节。楼上能否详细讲一下关于OB用户字节的问题,我不是太 ...

我暂时测试结果是ob里的其中一个位置可以保存两个字节。
你这么多内容用外部eeprom可能还好点,注意适当加大电源电容保证有足够的电维持eeprom更新完成。

fengyunyu 发表于 2018-4-13 09:11:42

擦鞋匠 发表于 2018-4-12 16:03
楼主使用循环去检测电压有点浪费CPU的嫌疑。pvd中断完全可以做到。

个人经验:stm32vct6 + keil


要多个备份区,上电只擦出一个备份区

苹果520 发表于 2018-4-14 14:20:11

rjx 发表于 2018-4-12 14:26
很简单,从整流后取出电压,再用2个电阻分压。见图:

正在测试中·········目前还没有测试ok。楼上说的是备份寄存器。但是量不大。

lnso 发表于 2019-9-21 13:56:59

擦鞋匠 发表于 2018-4-12 16:03
楼主使用循环去检测电压有点浪费CPU的嫌疑。pvd中断完全可以做到。

个人经验:stm32vct6 + keil


可否说下pvd中断的经验之谈?

gilberth 发表于 2022-1-26 21:28:12

感谢分享!
页: [1]
查看完整版本: 用STM32的PVD来做掉电保存数据,但不成功,求帮助(搞定了!)