FU68xx_5_Flash.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. /* -------------------------- (C) COPYRIGHT 2022 Fortiortech ShenZhen ---------------------------*/
  2. /**
  3. * @copyright (C) COPYRIGHT 2022 Fortiortech Shenzhen
  4. * @file
  5. * @author Fortiortech Appliction Team
  6. * @since Create:2022-07-14
  7. * @date Last modify:2022-07-14
  8. * @note Last modify author is Leo.li
  9. * @brief
  10. */
  11. /* Includes ------------------------------------------------------------------*/
  12. #include <FU68xx_5.h>
  13. #include <Myproject.h>
  14. ROM_TypeDef xdata FlashData;
  15. uint8 Flash_GetAddress(void);
  16. /**
  17. * @brief 读取固定地址值
  18. * @date 2022-07-14
  19. */
  20. uint8 ReadFlashValue(uint16 ReadAddress)
  21. {
  22. uint16 TempAddress0 = ReadAddress;
  23. __IO uint8 tevalue = 0; //临时变量
  24. tevalue = *(uint8 code *)TempAddress0; //读取回地址的值
  25. return tevalue;
  26. }
  27. /**
  28. * @brief 擦除指定扇区
  29. * @brief FlashAddress--Flash自擦除扇区内任意地址
  30. * @return 0--Flash自擦除成功,1--Flash自擦除失败
  31. * @date 2022-07-14
  32. */
  33. uint8 Flash_Sector_Erase(uint8 xdata * FlashAddress)
  34. {
  35. bool TempEA;
  36. uint16 TempFlashAddress;
  37. TempEA = EA;
  38. EA = 0;
  39. TempFlashAddress = (uint16)FlashAddress;
  40. if ((TempFlashAddress) < (0x7f00)) // 不擦除最后一个扇区
  41. {
  42. FLA_CR = 0x03; //使能自擦除
  43. FLA_KEY = 0x5a;
  44. FLA_KEY = 0x1f; //flash预编程解锁
  45. _nop_();
  46. *FlashAddress = 0xff; //写任意数据
  47. FLA_CR = 0x08; //开始预编程,完成后Flash再次上锁
  48. }
  49. EA = TempEA;
  50. if (ReadBit(FLA_CR, FLAERR))
  51. {
  52. return 1;
  53. }
  54. else
  55. {
  56. return 0;
  57. }
  58. }
  59. /**
  60. * @brief 擦除指定扇区
  61. * @brief FlashAddress--指定写入地址
  62. * @brief FlashData--写入数值
  63. * @return 0--Flash自擦除成功,1--Flash自擦除失败
  64. * @date 2022-07-14
  65. */
  66. void Flash_Sector_Write(uint8 xdata * FlashAddress, uint8 Flash_Data)
  67. {
  68. bool TempEA = 0;
  69. uint16 TempFlashAddress;
  70. uint8 idata Flash_Data_t = Flash_Data;
  71. TempEA = EA;
  72. EA = 0;
  73. TempFlashAddress = (uint16)FlashAddress;
  74. if ((TempFlashAddress) < 0x7f00) // 不编程最后一个扇区
  75. {
  76. FLA_CR = 0x01; // 使能Flash编程
  77. FLA_KEY = 0x5a;
  78. FLA_KEY = 0x1f; // flash预编程解锁
  79. _nop_();
  80. *(uint8 xdata *)FlashAddress = Flash_Data_t; // 写编程数据
  81. FLA_CR = 0x08; // 开始预编程,完成后Flash再次上锁
  82. }
  83. EA = TempEA;
  84. }
  85. /**
  86. * @brief WriteAddress--指定写入地址
  87. * @brief Length:写入数组长度
  88. * @brief value--写入数组
  89. * @date 2022-11-14
  90. */
  91. uint8 Flash_WriteValue(uint16 WriteAddress, uint8 Length, uint8 * str)
  92. {
  93. uint8 i;
  94. uint8 TempReadRomValue;
  95. uint16 FlashWriteAddr = WriteAddress;
  96. //读出有效数据
  97. for (i = 0; i < Length; i++)
  98. {
  99. Flash_Sector_Write(FlashWriteAddr + i, str[i]);
  100. TempReadRomValue = *(uint8 code *)(FlashWriteAddr + i);
  101. if (TempReadRomValue != str[i])
  102. {
  103. return 0;
  104. }
  105. }
  106. return 1;
  107. }
  108. /**
  109. * @brief 获取最后写入的地址,确认最新能写入的地址
  110. * @brief unsigned short FlashAddress:目标FLASH首地址
  111. * @brief uint8 Write_Length:写入数值长度
  112. */
  113. uint16 GetWrite_Black_Addr(unsigned short FlashAddress, uint8 Write_Length)
  114. {
  115. uint16 TempFlashAddress = 0;
  116. uint16 TempFirstAddress = 0; //用来保存保存首地址
  117. uint8 tempFlashData = 0xFF;
  118. uint8 Length = 0;
  119. TempFlashAddress = FlashAddress;
  120. TempFirstAddress = FlashAddress;
  121. while ((Length != Write_Length) && (TempFlashAddress < (TempFirstAddress + Write_Length))) //限定读取地址为当前页
  122. {
  123. tempFlashData = *(uint8 code *)(TempFlashAddress); //读取目标地址中数值是否为0
  124. if (tempFlashData == 0)
  125. {
  126. Length ++;
  127. TempFlashAddress += 1;
  128. }
  129. else
  130. {
  131. TempFirstAddress += Write_Length; //首地址跳转Write_Length字节
  132. if (TempFirstAddress > 0x7f00)
  133. {
  134. TempFirstAddress = 0x7f00;
  135. }
  136. TempFlashAddress = TempFirstAddress;
  137. Length = 0;
  138. }
  139. }
  140. return TempFirstAddress;
  141. }
  142. /**
  143. * @brief 读取Length字节数据,
  144. * @Input unsigned short BlockStartAddr:目标FLASH首地址
  145. * @Input uint8 Length:数值长度
  146. * @Input uint8 * str :读回数值写入数组
  147. * @ruturn Flash数据
  148. */
  149. void ReadFromFlash(unsigned short BlockStartAddr, uint8 Length, uint8 * str)
  150. {
  151. uint8 i = 0;
  152. for (i = 0; i < Length; i++)
  153. {
  154. str[i] = *(uint8 code *)(BlockStartAddr + i);
  155. }
  156. }
  157. /**
  158. * @brief 扇区擦除
  159. * @Input
  160. * @ruturn
  161. */
  162. void Flash_Erase(void)
  163. {
  164. uint8 FlashEraseStatus = 0;
  165. FlashEraseStatus = Flash_Sector_Erase(START_WriteADDRESS);
  166. if (!FlashEraseStatus)
  167. {
  168. /*----- 获取写入首地址 -----*/
  169. FlashData.WriteAddress = GetWrite_Black_Addr(START_WriteADDRESS, Write_Lenght);
  170. }
  171. else
  172. {
  173. FlashEraseStatus = Flash_Sector_Erase(START_WriteADDRESS);
  174. FlashData.WriteAddress = START_WriteADDRESS; //第一次擦写失败后第二次擦写,强行给地址
  175. /*----- 第二次擦写再失败,默认为Flash损坏,不进行处理 -----*/
  176. if (FlashEraseStatus)
  177. {
  178. ;
  179. }
  180. }
  181. FlashData.Flag_FlashErase = 0;
  182. }
  183. /**
  184. * @brief 保存按键
  185. * @date 2022-11-14
  186. */
  187. void Save_KeyValue(void)
  188. {
  189. uint8 FlashWriteStatus = 0; //返回值
  190. uint8 TempReadValue = 0;
  191. FlashData.WriteValue[0] = KS.KeyValuetotal;
  192. if (FlashData.ReadValue[0] != FlashData.WriteValue[0]) //确认写入前后数据不一致
  193. {
  194. EA = 0;
  195. while (!FlashWriteStatus) //写入异常,换到下个地址写入
  196. {
  197. FlashWriteStatus = Flash_WriteValue(FlashData.WriteAddress, Write_Lenght, FlashData.WriteValue);
  198. if (FlashWriteStatus)
  199. {
  200. Flash_Sector_Write(FlashData.WriteAddress + Verify_Bit, Verify_Ture);
  201. TempReadValue = *(uint8 code *)(FlashData.WriteAddress + Verify_Bit);
  202. /*----- 更新读取Flash首地址 -----*/
  203. FlashData.ReadAddress = FlashData.WriteAddress - Write_Lenght;
  204. /*----- 读取数值到FlashData.ReadValue -----*/
  205. ReadFromFlash(FlashData.ReadAddress, Write_Lenght, FlashData.ReadValue);
  206. if (TempReadValue == Verify_Ture)
  207. {
  208. goto exit;
  209. }
  210. else
  211. {
  212. FlashWriteStatus = 0;
  213. }
  214. }
  215. else
  216. {
  217. Flash_Sector_Write(FlashData.WriteAddress + Verify_Bit, Verify_Error);
  218. FlashData.WriteAddress = FlashData.WriteAddress + Write_Lenght;
  219. if (FlashData.WriteAddress > START_WriteADDRESS + 0x70)
  220. {
  221. FlashData.Flag_FlashErase = 1; //写到扇区最后字节,依然失败,直接进行数值清楚
  222. goto exit;
  223. }
  224. }
  225. }
  226. exit:
  227. EA = 1;
  228. }
  229. }