最近我做的一个项目想用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;
- }
|