[N32G03x] FLASH页擦除时间问题

[复制链接]
2805|11
 楼主| shipeng1989 发表于 2021-12-31 16:55 | 显示全部楼层 |阅读模式
最近我做的一个项目想用FLASH的最末页保存4个字节的用户数据,基于数据量很小,为了尽量减少对FLASH的擦写次数:采用动态地址读写,每次有数据变更则读写地址后移4字节直到写完一整页后再擦除一次FLASH页后从页起始开始写入4个字节。为了进一步减少对FLASH的擦写次数同时方便编程,我想通过PVD检测,每次用户断电后进入PVD中断先复位所有IO时钟以减少电流消耗,再检查数据写入请求标志是否将RAM数据写入FLASH,但是PVD检测的最高电压是2.4V,在电压下降到2V之前还有大概50毫秒的时间具体见下图波形:
微信图片_20211231164701.jpg
目前在FLASH没有擦除的情况下数据保存是没有问题的,我想请教下国民的大佬们我这么做会不会存在隐患,如果一页写满需要擦除FLASH页则这个时间和电压能不能保证正常工作。
以下附上源代码:

  1. /**
  2. * [url=home.php?mod=space&uid=247401]@brief[/url]  This function handles the PVD Output interrupt request defined in main.h .
  3. */

  4. void PVD_IRQHandler(void)
  5. {
  6.     if (EXTI_GetITStatus(EXTI_LINE16) != RESET)
  7.     {
  8.         /* Clear the Key Button EXTI line pending bit */
  9.         EXTI_ClrITPendBit(EXTI_LINE16);

  10.                 RCC->APB2PRST |= 0xD69D;
  11.         if (0xA5==ee_request)WriteEepData();
  12.                 while (1);
  13.     }
  14. }

  15. uint16_t FindEepData(void)
  16. {
  17.         uint16_t page_offset;
  18.         for (page_offset=0;page_offset<FLASH_PAGE_SIZE/4-1;page_offset++)
  19.         {
  20.                 if (*((uint32_t*)EEPROM_BLOCK+page_offset+1)==0xFFFFFFFF)break;
  21.         }
  22.         return page_offset;
  23. }

  24. void LoadEepData(void)
  25. {
  26.         uint8_t rbuff[4];
  27.         uint16_t page_offset = FindEepData();
  28.         *(uint32_t*)rbuff = *((uint32_t*)EEPROM_BLOCK+page_offset);

  29.         PC_TXVOLUME = rbuff[0]!=0xFF?rbuff[0]:0x05;

  30.         PC_TXVSPEED = rbuff[1]!=0xFF?rbuff[1]:0x05;

  31.         PC_TXPWH8 = rbuff[2]!=0xFF?rbuff[2]:0;

  32.         PC_TXPWL8 = rbuff[3]!=0xFF?rbuff[3]:0;
  33. }

  34. void SYN6658_Config(void)
  35. {
  36.         char cmd_string[]="[vxx][sxx][mxx]";
  37.         uint8_t i = PC_TXVOLUME&15;
  38.         cmd_string[2] = '0'+i/10;
  39.         cmd_string[3] = '0'+i%10;
  40.         i = PC_TXVSPEED&15;
  41.         cmd_string[7] = '0'+i/10;
  42.         cmd_string[8] = '0'+i%10;
  43.         i = PC_TXVSPEED>>4;
  44.         cmd_string[12] = i==0?'0':'5';
  45.         cmd_string[13] = i==0?'3':'0'+i;
  46.         VoicePrintf(cmd_string);
  47.         while (syn6658_status==0);
  48.         delay_ms(100);
  49. }

  50. uint8_t WriteEepData(void)
  51. {
  52.         uint8_t        res = 0,wbuf8[4]={0xFF,0xFF,0xFF,0xFF};
  53.         uint16_t page_offset = FindEepData();
  54.         uint32_t buf32 = *((uint32_t*)EEPROM_BLOCK+page_offset);
  55.         wbuf8[0]=PC_TXVOLUME;wbuf8[1]=PC_TXVSPEED;
  56.         wbuf8[2]=PC_TXPWH8;wbuf8[3]=PC_TXPWL8;
  57.         if (buf32==*((uint32_t*)wbuf8))return 0;
  58.         /* Unlocks the FLASH Program Erase Controller */
  59.         FLASH_Unlock();
  60.         /* Program FLASH */
  61.         if (buf32!=0xFFFFFFFF)
  62.         {
  63.                 page_offset++;page_offset &= PAGE_SIZE_MASK>>2;
  64.                 buf32 = *((uint32_t*)EEPROM_BLOCK+page_offset);
  65.                 /* Erase */
  66.                 if (buf32!=0xFFFFFFFF && FLASH_COMPL != FLASH_EraseOnePage(EEPROM_BLOCK))
  67.                 {
  68.                         res=1;goto        EXIT;
  69.                 }
  70.         }

  71.         /* Program */
  72.         if (FLASH_COMPL != FLASH_ProgramWord(EEPROM_BLOCK + page_offset*4, *(uint32_t*)wbuf8))
  73.         {
  74.                 res=2;
  75.         }

  76.         EXIT:
  77.         /* Locks the FLASH Program Erase Controller */
  78.         FLASH_Lock();
  79.         return        res;
  80. }


画个朴昧 发表于 2021-12-31 18:12 | 显示全部楼层
030系列页(512字节)擦除时间,全文下典型值为2.27ms,数据手册中有介绍,基于你的应用场景可以自行评估,
同时可以提个建议参考:擦写flash前先检测VDD电压,VDD满足大于3V再进行flash操作可减少风险。
 楼主| shipeng1989 发表于 2022-1-1 13:57 | 显示全部楼层
画个朴昧 发表于 2021-12-31 18:12
030系列页(512字节)擦除时间,全文下典型值为2.27ms,数据手册中有介绍,基于你的应用场景可以自行评估, ...

感谢大佬百忙之中抽身给我解答问题,2.27ms的擦除时间真是神速啊,只是要检测VDD电压大于3V看来我这个PVD检测方案就不能用了,只能用一个单独的IO来检测VDD的上一级电压了
cjseng 发表于 2022-1-1 15:53 | 显示全部楼层
平时最后4个字节不用,还剩4个字节时就擦除。
掉电瞬间,直接写到最后4个字节,以避免擦除。
这样是否可以?
 楼主| shipeng1989 发表于 2022-1-2 14:40 | 显示全部楼层
cjseng 发表于 2022-1-1 15:53
平时最后4个字节不用,还剩4个字节时就擦除。
掉电瞬间,直接写到最后4个字节,以避免擦除。
这样是否可以 ...

兄弟你的意思是上电读数据的时候如果发现数据已经记录到页的最后4个字节就备份数据擦除页再将数据写回页首地址?从而保证下次掉电保存时不需要执行页擦除操作?

评论

或者你干脆用最后两页用来保存数据,交替写,写满一页后,写入另一页,同时将原先页面擦除。  发表于 2022-1-2 18:31
对,就是这个意思,应该不会每次都是在掉电瞬间需要保存数据吧,这样一来,也不会影响寿命  发表于 2022-1-2 18:28
 楼主| shipeng1989 发表于 2022-1-2 22:06 | 显示全部楼层
你可能还没完全理解我的问题,我的数据就是在掉电瞬间才保存的,因为上电状态用户可能会多次修改但我都不会写入flash保存,只会立个flag等到pvd检测到掉电了再进pvd中断检查这个flag判断是否要执行flash写入操作。另外你说的两个页交替的办法可行,总之擦除操作只能放到上电状态判断进行,掉电时只做写入不做擦除操作。
画个朴昧 发表于 2022-1-3 14:00 | 显示全部楼层
shipeng1989 发表于 2022-1-2 22:06
你可能还没完全理解我的问题,我的数据就是在掉电瞬间才保存的,因为上电状态用户可能会多次修改但我都不会 ...

还有一个方法可以考虑,定一个32bit的变量放在bin文件的最后四字节,掉电时只需要对比变量赋值即可,变量的位置随bin大小动态变化。
 楼主| shipeng1989 发表于 2022-1-3 14:38 | 显示全部楼层
画个朴昧 发表于 2022-1-3 14:00
还有一个方法可以考虑,定一个32bit的变量放在bin文件的最后四字节,掉电时只需要对比变量赋值即可,变量 ...

不知道您说的bin文件指的是程序文件吗?您的意思是从程序的末尾可以一直写下去直到写完整个flash?
mutable 发表于 2022-1-5 14:31 | 显示全部楼层
这波形,怎么还拐两道弯
画个朴昧 发表于 2022-1-7 18:17 | 显示全部楼层
shipeng1989 发表于 2022-1-3 14:38
不知道您说的bin文件指的是程序文件吗?您的意思是从程序的末尾可以一直写下去直到写完整个flash? ...

个人认为还是有两种方法:1.bin即程序文件的后面留四个自己变量写你的值,PVD时你去检测是否需要去修改变量值;2.按照你所说的可以上电擦除,下电写数据。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

30

主题

140

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部