OpenEdv-开源电子网

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

用STM32的PVD功能实现掉电保存,不成功,求帮助

[复制链接]

64

主题

249

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1073
金钱
1073
注册时间
2017-6-10
在线时间
279 小时
发表于 2017-8-1 14:26:01 | 显示全部楼层 |阅读模式
1金钱
本帖最后由 rjx007 于 2017-8-2 14:17 编辑

想用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线路挂起位        
}





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

使用道具 举报

64

主题

249

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1073
金钱
1073
注册时间
2017-6-10
在线时间
279 小时
 楼主| 发表于 2017-8-1 16:39:07 | 显示全部楼层
沉得好快,继续求解。
回复

使用道具 举报

64

主题

249

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1073
金钱
1073
注册时间
2017-6-10
在线时间
279 小时
 楼主| 发表于 2017-8-2 09:50:24 | 显示全部楼层
本帖最后由 rjx007 于 2017-8-2 09:57 编辑

回楼上:
也曾怀疑是时间不够,遂将3.3V的滤波电容加大到1500U,仍不行,实在想不出原因了。
我曾试过用ADC来检测电源电压,设定电压跌落至2.9V时,将数据写入EEPROM,此时滤波电容仅用220U,且从ADC得到数据到写EEPROM,使用的是还是查询方式,做了上百次试验,都能非常可靠的保存数据。
按理讲PVD用得的是中断,要比ADC快得多吧?
再说两者都是写相同的EEPROM,更何况才仅仅写一个数据呢?
用ADC保存数据:

//掉电记忆
void pwr_down(void)
{     
   if(ad<=3360)
      {                  
         AT24CXX_WriteOneByte(0x02,VOLUME_1);                 //write_eep(0x02,VOLUME_1);         
         delay_ms(10);        
      }
}


回复

使用道具 举报

64

主题

249

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1073
金钱
1073
注册时间
2017-6-10
在线时间
279 小时
 楼主| 发表于 2017-8-2 14:04:35 | 显示全部楼层
本帖最后由 rjx007 于 2017-8-2 14:12 编辑

终于搞定了!根本不用这么复杂,用简单的查询方式就可以了,几条语句就行了,与大家分享:思路非常务实:
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);                 
                     }
        }

}
回复

使用道具 举报

25

主题

683

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1351
金钱
1351
注册时间
2012-4-25
在线时间
195 小时
发表于 2017-8-2 21:53:38 | 显示全部楼层
用中断写吧,曾经在中断中 写进一页的数据,就是64byte
1-1
回复

使用道具 举报

7

主题

163

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2762
金钱
2762
注册时间
2017-5-17
在线时间
430 小时
发表于 2017-8-2 22:18:44 | 显示全部楼层
没用过,,,来看看。。
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-4-20 06:04

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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