用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线路挂起位
} 我觉得问题出在这里:EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising; 改Falling试试 终于搞定了!根本不用这么复杂,用简单的查询方式就可以了,几条语句就行了,与大家分享:思路非常务实:
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);
}
}
} 好像ADC中有个窗口看门狗的功能 这个是可以用中断的,如果用这个,不知道与楼主的查询方式能不能达到一样的效果 用ADC来检测电源电压的方式,是完全可以的,我原来在PIC,AVR单片机中一直用此法。改用STM32 后,也一直用ADC的方式,要注意的是采样电压要取自整流滤波后,7805稳压前的大电解上,再用2个电阻分压。滤波大电解的容量不能小于3300U.
最近才研究用STM32的PVD功能,也是可行的,最大的好处是没有外部电路,非常方便。 请问STM32的PVD有没有具体的引脚,如果没有会不会来不及保存,谢谢 电压检测精度如何,能否作为欠压报警,有待测试! 回楼上2位:
1、PVD没有具体引脚。滤波电容用大些时间是足够的。
2、完全可以做欠压报警用。 rjx 发表于 2017-8-10 09:45
回楼上2位:
1、PVD没有具体引脚。滤波电容用大些时间是足够的。
2、完全可以做欠压报警用。 ...
滤波电容取多大? rjx 发表于 2017-8-2 14:55
用ADC来检测电源电压的方式,是完全可以的,我原来在PIC,AVR单片机中一直用此法。改用STM32 后,也一直用A ...
大电容,上电时电流大,升压慢,掉电也慢,可能会有复位问题 主滤波电容用3300U,没有发现什么问题。 rjx 发表于 2018-2-13 10:58
主滤波电容用3300U,没有发现什么问题。
可以贴出这部分电路吗?我的项目上正打算用这部分电路. 本帖最后由 rjx 于 2018-4-12 14:28 编辑
很简单,从整流后取出电压,再用2个电阻分压。见图: 才1个字节的数据不需要外部eeprom,直接保存在OB里面的用户字节里即可 运行中还要保存其他的数据,但也不多,只有7-8个字节。楼上能否详细讲一下关于OB用户字节的问题,我不是太懂。先谢谢了。 楼主使用循环去检测电压有点浪费CPU的嫌疑。pvd中断完全可以做到。
个人经验:stm32vct6 + keil
不管是使用eeprom还是flash保存数据,在写入数据前都需要先擦除相应的存储器(上电擦除这段存储空间,掉电写入这段存储空间,以节约时间)。因为擦除的时间是很长的,在擦除的这段时间内足以写入上百字节数据(我在pvd中断里写入不低于100字节数据)。
例如:25lc512每擦除一个page(一个page是256字节)的时间典型值是5ms。
rjx 发表于 2018-4-12 14:36
运行中还要保存其他的数据,但也不多,只有7-8个字节。楼上能否详细讲一下关于OB用户字节的问题,我不是太 ...
我暂时测试结果是ob里的其中一个位置可以保存两个字节。
你这么多内容用外部eeprom可能还好点,注意适当加大电源电容保证有足够的电维持eeprom更新完成。 擦鞋匠 发表于 2018-4-12 16:03
楼主使用循环去检测电压有点浪费CPU的嫌疑。pvd中断完全可以做到。
个人经验:stm32vct6 + keil
要多个备份区,上电只擦出一个备份区 rjx 发表于 2018-4-12 14:26
很简单,从整流后取出电压,再用2个电阻分压。见图:
正在测试中·········目前还没有测试ok。楼上说的是备份寄存器。但是量不大。 擦鞋匠 发表于 2018-4-12 16:03
楼主使用循环去检测电压有点浪费CPU的嫌疑。pvd中断完全可以做到。
个人经验:stm32vct6 + keil
可否说下pvd中断的经验之谈? 感谢分享!
页:
[1]