FLASH.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. #include "FLASH.h"
  2. #include "usart.h"
  3. #include "stdio.h"
  4. #include <string.h> // 包含 strlen 的头文件
  5. /*************下面所有的数都必须是4字节对齐的******************/
  6. /***************************************************************
  7. * 函数名称: Flash_GetBank
  8. * 说 明: 获得传入地址所在Bank
  9. * 参 数: faddr,Flash地址
  10. * 返 回 值: Bank值
  11. ***************************************************************/
  12. uint32_t Flash_GetBank(uint32_t faddr)
  13. {
  14. if (READ_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_MEM_MODE_Pos) == 0)
  15. {
  16. if (faddr < (FLASH_BASE + FLASH_BANK_SIZE))
  17. return FLASH_BANK_1;
  18. else
  19. return FLASH_BANK_1;
  20. }
  21. else
  22. {
  23. if (faddr < (FLASH_BASE + FLASH_BANK_SIZE)) // bank swap
  24. return FLASH_BANK_1;
  25. else
  26. return FLASH_BANK_1;
  27. }
  28. }
  29. /***************************************************************
  30. * 函数名称: Flash_GetPage
  31. * 说 明: 获得传入地址所在Page
  32. * 参 数: faddr,Flash地址
  33. * 返 回 值: Bank值
  34. ***************************************************************/
  35. uint32_t Flash_GetPage(uint32_t faddr)
  36. {
  37. if (faddr < (FLASH_BASE + FLASH_BANK_SIZE))
  38. return (faddr - FLASH_BASE) / FLASH_PAGE_SIZE;
  39. else
  40. return (faddr - (FLASH_BASE + FLASH_BANK_SIZE)) / FLASH_PAGE_SIZE;
  41. }
  42. /***************************************************************
  43. * 函数名称: Flash_ReadOneWord
  44. * 说 明: 从指定地址中读取一个32位的数据
  45. * 参 数: faddr,Flash地址
  46. * 返 回 值: Flash地址内的一个32位的数据
  47. ***************************************************************/
  48. uint32_t Flash_ReadOneWord(uint32_t faddr)
  49. {
  50. return *(__IO uint32_t *)faddr;
  51. }
  52. /***************************************************************
  53. * 函数名称: Flash_ErasePages
  54. * 说 明: 擦除页
  55. * 参 数: faddr,起始地址
  56. * fdataNum,要擦除的字数,实际上也是整页擦除
  57. * 返 回 值: 无
  58. ***************************************************************/
  59. void Flash_ErasePages(uint32_t faddr,uint32_t fdataNum)
  60. {
  61. if(fdataNum == 0||faddr>FLASH_ADDR_MAX)
  62. {
  63. return;
  64. }
  65. uint32_t PageError = 0;
  66. HAL_FLASH_Unlock();
  67. FLASH_EraseInitTypeDef FLASH_EraseInitSturcture;
  68. __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
  69. FLASH_EraseInitSturcture.TypeErase = FLASH_TYPEERASE_PAGES;
  70. FLASH_EraseInitSturcture.Banks = Flash_GetBank(faddr);
  71. FLASH_EraseInitSturcture.Page = Flash_GetPage(faddr);
  72. FLASH_EraseInitSturcture.NbPages = Flash_GetPage(faddr + 4 * fdataNum - 1) - FLASH_EraseInitSturcture.Page + 1;
  73. if(HAL_FLASHEx_Erase(&FLASH_EraseInitSturcture,&PageError) != HAL_OK)
  74. {
  75. HAL_FLASH_Lock();
  76. return;
  77. }
  78. }
  79. /***************************************************************
  80. * 函数名称: Flash_WriteOneWord
  81. * 说 明: 向指定地址中写入一个32位的数据
  82. * 参 数: faddr,Flash地址
  83. * fdata32,Flash地址内的一个32位的数据
  84. * 返 回 值: 写FLASH返回的状态
  85. ***************************************************************/
  86. uint8_t Flash_WriteOneWord(uint32_t faddr,uint32_t fdata32)
  87. {
  88. if(faddr<FLASH_BASE) //非法地址
  89. return HAL_ERROR;
  90. uint8_t FLASH_STATUS;
  91. uint64_t fdata64;
  92. HAL_FLASH_Unlock();
  93. if(faddr<FLASH_ADDR_MAX) //写入数据地址小于STM32L431RC的flash地址最大值
  94. {
  95. fdata64 = fdata32|0xffffffff00000000uL;
  96. FLASH_STATUS = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD,faddr,fdata64);//写入数据
  97. }
  98. HAL_FLASH_Lock();
  99. return FLASH_STATUS;
  100. }
  101. /***************************************************************
  102. * 函数名称: Flash_WriteDoubleWord
  103. * 说 明: 向指定地址中写入一个双字(64位)数据
  104. * 参 数: faddr,Flash地址
  105. * fdata64,Flash地址内的一个双字(64位)数据
  106. * 返 回 值: 写FLASH返回的状态
  107. ***************************************************************/
  108. uint8_t Flash_WriteDoubleWord(uint32_t faddr,uint64_t fdata64)
  109. {
  110. if(faddr<FLASH_BASE) //非法地址
  111. return HAL_ERROR;
  112. uint8_t FLASH_STATUS;
  113. HAL_FLASH_Unlock(); //解锁FLASH
  114. if(faddr<FLASH_ADDR_MAX) //写入数据地址小于STM32L431RC的flash地址最大值
  115. {
  116. FLASH_STATUS = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD,faddr,fdata64);//写入数据
  117. }
  118. HAL_FLASH_Lock(); //上锁
  119. return FLASH_STATUS;
  120. }
  121. /***************************************************************
  122. * 函数名称: Flash_Write32
  123. * 说 明: 向指定地址中写入fdataNum个32位的数据
  124. * 参 数: faddr,Flash起始地址
  125. * fdata,Flash地址内的32位的数据指针
  126. * fdata32Num,要写入的字(32位)数的数量
  127. * 返 回 值: 无
  128. ***************************************************************/
  129. void Flash_Write32(uint32_t faddr,uint32_t *fdata32, uint32_t fdata32Num)
  130. {
  131. uint64_t fdata64;
  132. HAL_FLASH_Unlock(); //解锁FLASH
  133. if(faddr<FLASH_ADDR_MAX) //写入数据地址小于STM32L431RC的flash地址最大值
  134. {
  135. for (uint32_t i = 0; i < fdata32Num / 2; i++)
  136. {
  137. fdata64 = *(uint64_t*)fdata32;
  138. if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, faddr, fdata64) != HAL_OK)
  139. { //如果出现错误
  140. HAL_FLASH_Lock(); //锁定FLASH
  141. return;
  142. }
  143. faddr += 8;
  144. fdata32 += 2;
  145. }
  146. if ((fdata32Num & 0x01) == 1)
  147. {
  148. uint64_t fdata64 = *(uint64_t*)faddr;
  149. fdata64 = (fdata64 & 0xffffffff00000000uL) | (*fdata32);
  150. if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, faddr, fdata64) != HAL_OK)
  151. { //如果出现错误
  152. HAL_FLASH_Lock(); //锁定FLASH
  153. return;
  154. }
  155. }
  156. }
  157. HAL_FLASH_Lock();
  158. }
  159. /***************************************************************
  160. * 函数名称: Flash_Write64
  161. * 说 明: 向指定地址中写入fdataNum个64位的数据
  162. * 参 数: faddr,Flash起始地址
  163. * fdata,Flash地址内的64位的数据指针
  164. * fdata64Num,要写入的字(64位)数的数量
  165. * 返 回 值: 无
  166. ***************************************************************/
  167. void Flash_Write64(uint32_t faddr,uint64_t *fdata64, uint32_t fdata64Num)
  168. {
  169. HAL_FLASH_Unlock(); //解锁FLASH
  170. if(faddr<FLASH_ADDR_MAX) //写入数据地址小于STM32L431RC的flash地址最大值
  171. {
  172. for (uint32_t i = 0; i < fdata64Num; i++)
  173. {
  174. if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, faddr, *fdata64) != HAL_OK)
  175. { //如果写入异常
  176. HAL_FLASH_Lock(); //上锁FLASH
  177. return;
  178. }
  179. faddr += 8;
  180. fdata64 += 1;
  181. }
  182. }
  183. HAL_FLASH_Lock(); //上锁FLASH
  184. }
  185. /***************************************************************
  186. * 函数名称: Flash_Read32
  187. * 说 明: 从指定地址开始读出指定长度的数据
  188. * 参 数: ReadAddr,起始地址
  189. * *pBuffer,数据指针
  190. * fdata32Num,字(32位)数
  191. * 返 回 值: 无
  192. ***************************************************************/
  193. void Flash_Read32(uint32_t faddr,uint32_t *fdata32,uint32_t fdata32Num)
  194. {
  195. uint32_t i;
  196. if(faddr>FLASH_ADDR_MAX) //地址小于STM32L431RC的flash地址最大值
  197. return;
  198. for(i=0;i<fdata32Num;i++)
  199. {
  200. fdata32[i] = Flash_ReadOneWord(faddr); //读取4个字节
  201. faddr+=4;
  202. }
  203. }
  204. /***************************************************************
  205. * 函数名称: FlashRead
  206. * 说 明: 从指定地址开始读出指定长度的数据
  207. * 参 数: ReadAddr,起始地址
  208. * *pBuffer,数据指针
  209. * fdata8Num,字(8位)数
  210. * 返 回 值: 无
  211. ***************************************************************/
  212. void Flash_ReadBytes(uint32_t faddr,uint8_t *fdata8,uint32_t fdata8Num)
  213. {
  214. uint32_t i;
  215. if(faddr>FLASH_ADDR_MAX) //地址小于STM32L431RC的flash地址最大值
  216. return;
  217. for(i=0;i<fdata8Num;i++)
  218. {
  219. fdata8[i] = *(__IO uint8_t *)faddr; //读取1个字节
  220. faddr+=1;
  221. }
  222. }
  223. /***************************************************************
  224. * 函数名称: Flash_WriteRead
  225. * 说 明: Flash数据写入、读取测试
  226. * 参 数: fAdress,flash地址
  227. * *wData,向flash地址里写入的数据
  228. * wDataLen,写入数据的长度
  229. * *rData,从flash地址里读出的数据
  230. * 返 回 值: ERROR,失败
  231. * SUCCESS,成功
  232. ***************************************************************/
  233. uint8_t Flash_WriteRead(uint32_t fAdress, uint8_t *wData, uint32_t wDataLen, uint8_t *rData)
  234. {
  235. char str_adc_vol[200];
  236. char str_read_vol[200];
  237. if (wData == NULL)
  238. {
  239. return ERROR;
  240. }
  241. uint16_t strWriteLen = (wDataLen % 4) == 0 ? (wDataLen / 4) : (wDataLen / 4 + 1);
  242. // 将 wData 转换为十六进制字符串
  243. str_adc_vol[0] = '\0';
  244. for (uint32_t i = 0; i < wDataLen; i++)
  245. {
  246. sprintf(str_adc_vol + strlen(str_adc_vol), "%02X ", wData[i]);
  247. }
  248. printf("Flash_Write32: %s\r\n", str_adc_vol);
  249. Flash_ErasePages(fAdress, 1); // 擦除flash
  250. Flash_Write32(fAdress, (uint32_t *)wData, strWriteLen); // 写入数据
  251. Flash_ReadBytes(fAdress,rData, wDataLen); // 读出数据
  252. // 将 rData 转换为十六进制字符串
  253. str_read_vol[0] = '\0';
  254. for (uint32_t i = 0; i < wDataLen; i++)
  255. {
  256. sprintf(str_read_vol + strlen(str_read_vol), "%02X ", rData[i]);
  257. }
  258. printf("Flash_ReadBytes: %s\r\n", str_read_vol);
  259. return SUCCESS;
  260. }
  261. /**********************END OF FILE**********************/