客户用国民技术-N32G030做的一个项目想用FLASH的最末页保存4个字节的用户数据,基于数据量很小,为了尽量减少对FLASH的擦写次数:采用动态地址读写,每次有数据变更则读写地址后移4字节直到写完一整页后再擦除一次FLASH页后从页起始开始写入4个字节。为了进一步减少对FLASH的擦写次数同时方便编程,想通过PVD检测,每次用户断电后进入PVD中断先复位所有IO时钟以减少电流消耗,再检查数据写入请求标志是否将RAM数据写入FLASH,但是PVD检测的最高电压是2.4V,在电压下降到2V之前还有大概50毫秒的时间具体见下图波形:
	
	目前在FLASH没有擦除的情况下数据保存是没有问题的,客户问题:这么做会不会存在隐患,如果一页写满需要擦除FLASH页则这个时间和电压能不能保证正常工作。
	以下附上源代码:
	
	
	/**
	* [url=home.php?mod=space&uid=247401]@brief[/url]  This function handles the PVD Output interrupt request defined in main.h .
	*/
	
	void PVD_IRQHandler(void)
	{
	    if (EXTI_GetITStatus(EXTI_LINE16) != RESET)
	    {
	        /* Clear the Key Button EXTI line pending bit */
	        EXTI_ClrITPendBit(EXTI_LINE16);
	
	                RCC->APB2PRST |= 0xD69D;
	        if (0xA5==ee_request)WriteEepData();
	                while (1);
	    }
	}
	
	uint16_t FindEepData(void)
	{
	        uint16_t page_offset;
	        for (page_offset=0;page_offset<FLASH_PAGE_SIZE/4-1;page_offset++)
	        {
	                if (*((uint32_t*)EEPROM_BLOCK+page_offset+1)==0xFFFFFFFF)break;
	        }
	        return page_offset;
	}
	
	void LoadEepData(void)
	{
	        uint8_t rbuff[4];
	        uint16_t page_offset = FindEepData();
	        *(uint32_t*)rbuff = *((uint32_t*)EEPROM_BLOCK+page_offset);
	
	        PC_TXVOLUME = rbuff[0]!=0xFF?rbuff[0]:0x05;
	
	        PC_TXVSPEED = rbuff[1]!=0xFF?rbuff[1]:0x05;
	
	        PC_TXPWH8 = rbuff[2]!=0xFF?rbuff[2]:0;
	
	        PC_TXPWL8 = rbuff[3]!=0xFF?rbuff[3]:0;
	}
	
	void SYN6658_Config(void)
	{
	        char cmd_string[]="[vxx][sxx][mxx]";
	        uint8_t i = PC_TXVOLUME&15;
	        cmd_string[2] = '0'+i/10;
	        cmd_string[3] = '0'+i%10;
	        i = PC_TXVSPEED&15;
	        cmd_string[7] = '0'+i/10;
	        cmd_string[8] = '0'+i%10;
	        i = PC_TXVSPEED>>4;
	        cmd_string[12] = i==0?'0':'5';
	        cmd_string[13] = i==0?'3':'0'+i;
	        VoicePrintf(cmd_string);
	        while (syn6658_status==0);
	        delay_ms(100);
	}
	
	uint8_t WriteEepData(void)
	{
	        uint8_t        res = 0,wbuf8[4]={0xFF,0xFF,0xFF,0xFF};
	        uint16_t page_offset = FindEepData();
	        uint32_t buf32 = *((uint32_t*)EEPROM_BLOCK+page_offset);
	        wbuf8[0]=PC_TXVOLUME;wbuf8[1]=PC_TXVSPEED;
	        wbuf8[2]=PC_TXPWH8;wbuf8[3]=PC_TXPWL8;
	        if (buf32==*((uint32_t*)wbuf8))return 0;
	        /* Unlocks the FLASH Program Erase Controller */
	        FLASH_Unlock();
	        /* Program FLASH */
	        if (buf32!=0xFFFFFFFF)
	        {
	                page_offset++;page_offset &= PAGE_SIZE_MASK>>2;
	                buf32 = *((uint32_t*)EEPROM_BLOCK+page_offset);
	                /* Erase */
	                if (buf32!=0xFFFFFFFF && FLASH_COMPL != FLASH_EraseOnePage(EEPROM_BLOCK))
	                {
	                        res=1;goto        EXIT;
	                }
	        }
	
	        /* Program */
	        if (FLASH_COMPL != FLASH_ProgramWord(EEPROM_BLOCK + page_offset*4, *(uint32_t*)wbuf8))
	        {
	                res=2;
	        }
	
	        EXIT:
	        /* Locks the FLASH Program Erase Controller */
	        FLASH_Lock();
	        return        res;
	}
	
	国民技术-N32G030系列(512字节)擦除时间,全文下典型值为2.27ms,数据手册中有介绍,基于应用场景可以自行评估,同时可以提个建议参考:擦写flash前先检测VDD电压,VDD满足大于3V再进行flash操作可减少风险。

 
   
   
   
  