stm32做PVD掉电检测保存数据到flash

2019-12-12 18:17发布

我用STM32做掉电检测,在检测到掉电后保存数据到flash,我已经检测到掉电了,而且已经进入PVD中断了,保存数据的函数也是执行完了的,但为什么就是数据没有保存成功呢?求大神指点!
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
73条回答
raydsp
1楼-- · 2019-12-21 03:18
Llinuxu 发表于 2016-5-31 14:04
初始化和一切配置好像我在前面是给出了的!写函数里面的察除只是做判断,你要自己之前先察除,然后写函数 ...

摖除函数使用整页摖除FLASH_ErasePage(uint32_t Page_Address)还是FLASH_EraseOptionBytes(void)摖除?
gaoxiaohu110
2楼-- · 2019-12-21 06:45
本帖最后由 gaoxiaohu110 于 2016-6-3 08:13 编辑
zeroXone 发表于 2016-5-30 20:55
系统运行起来一段时候之后才启用掉电检测和Flash功能呀,这样就很好避免你这个类似上电不稳定的情况啊。
...


关键不是上电电压不稳,是掉电,5.5v法拉电容通过一个3.3V的稳压芯片,当电压在1.8V附近时,文波有120MV,会出现电压不稳的情况,中断里做个LED灯翻转,会看到led在不停的闪烁
zeroXone
3楼-- · 2019-12-21 08:42
 精彩回答 2  元偷偷看……
gaoxiaohu110
4楼-- · 2019-12-21 10:44
zeroXone 发表于 2016-6-3 09:29
你是说程序还在挣扎,然后不停的进中断,然而你本意只进一次?进了中断搞个变量判断一下,宕机之前不再处 ...

这是一个方法,但是为什么会宕机呢,很奇怪的现象,在5.5v电容两端并联个10uf的电容滤波也不起作用?
raydsp
5楼-- · 2019-12-21 16:43
经过几天调试,写出可以使用的STM32  PVD掉电存储数据,目前只能一个扇区内存储数据,不过应该够用。希望可以帮助有需要的人。代码可能不是很严谨,需自己改进。
写入数据修改(摖除与写入分开):
void STMFLASH_Write(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)        //摖除
{
       
       
         
        u16 i;   
        u32 offaddr;   //去掉0X08000000后的地址
        if(WriteAddr<STM32_FLASH_BASE||(WriteAddr>=(STM32_FLASH_BASE+1024*STM32_FLASH_SIZE)))return;//非法地址
        FLASH_Unlock();                                                //解锁
        offaddr=WriteAddr-STM32_FLASH_BASE;                //实际偏移地址.0X08034000-0X08000000=0X00034000
        secpos=offaddr/STM_SECTOR_SIZE;                        //扇区地址  0~127 for STM32F103RBT6   16
        secoff=(offaddr%STM_SECTOR_SIZE)/2;                //在扇区内的偏移(2个字节为基本单位.)616
        secremain=STM_SECTOR_SIZE/2-secoff;                //扇区剩余空间大小   408
        if(NumToWrite<=secremain)secremain=NumToWrite;//不大于该扇区范围 4
        while(1)
        {       
                STMFLASH_Read(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//读出整个扇区的内容
                for(i=0;i<secremain;i++)//校验数据
                {
                        if(STMFLASH_BUF[secoff+i]!=0XFFFF)break;//需要擦除            
                }
                if(i<secremain)//需要擦除
                {
                        FLASH_ErasePage(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE);//擦除这个扇区
                        for(i=0;i<secremain;i++)//复制
                        {
                                STMFLASH_BUF[i+secoff]=pBuffer[i];          
                        }
               
                }       
if(NumToWrite==secremain)break;//摖除跳出
        }       
                                 
}
void STMFLASH_Writego(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)        //中断写入
{
       
                         STMFLASH_Write_NoCheck(WriteAddr,pBuffer,NumToWrite);//写已经擦除了的,直接写入扇区剩余区间.
       FLASH_Lock();//上锁                         
}


PVD初始化与中断函数:
void NVIC_pvdConfiguration(void)
{ static u16 TEXT_Buffer[4];
  NVIC_InitTypeDef NVIC_InitStructure;

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
//PVD
  NVIC_InitStructure.NVIC_IRQChannel = PVD_IRQn;//PVD_IRQChannel;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
  NVIC_Init(&NVIC_InitStructure);  


                    last_data[0]=lastNM;last_data[1]=lastNM2;//摖除之前需要将掉电存储到的数据转移到其他地方
                                                         STMFLASH_Write(FLASH_SAVE_LAST,(u16*)TEXT_Buffer,4);        
}
void ExterLineInterrupt(void)
{
    EXTI_InitTypeDef EXTI_InitStructure;
    EXTI_DeInit();
    EXTI_StructInit(&EXTI_InitStructure);
     PWR_PVDLevelConfig(PWR_PVDLevel_2V9); // ???????
    PWR_PVDCmd(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);
}
void PVD_IRQHandler(void)
{
        static u16 TEXT_Buffer[4];
       

        LCD_LED=0;
                EXTI_ClearITPendingBit(EXTI_Line16);//clear bit;
          
                                                 STMFLASH_Writego(FLASH_SAVE_LAST,(u16*)TEXT_Buffer,4); //写入需要保存的数据

   if (PWR_GetFlagStatus(PWR_FLAG_PVDO)== SET) {
                 PWR_ClearFlag(PWR_FLAG_PVDO);
   
    }
  
}
cumt_123456
6楼-- · 2019-12-21 19:45
供电电压影响flash读写,可以降低读写速度设置,调低flash电压等级,测试下。

一周热门 更多>