Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 
 

150 Zeilen
5.2 KiB

  1. #include "stmflash.h"
  2. #include "delay.h"
  3. #include "usart.h"
  4. //读取指定地址的字(32位数据)
  5. //faddr:读地址
  6. //返回值:对应数据.
  7. u32 STMFLASH_ReadWord(u32 faddr)
  8. {
  9. return *(__IO uint32_t *)faddr;
  10. }
  11. //获取某个地址所在的flash扇区
  12. //addr:flash地址
  13. //返回值:0~11,即addr所在的扇区
  14. uint16_t STMFLASH_GetFlashSector(u32 addr)
  15. {
  16. if(addr<ADDR_FLASH_SECTOR_1)return FLASH_SECTOR_0;
  17. else if(addr<ADDR_FLASH_SECTOR_2)return FLASH_SECTOR_1;
  18. else if(addr<ADDR_FLASH_SECTOR_3)return FLASH_SECTOR_2;
  19. else if(addr<ADDR_FLASH_SECTOR_4)return FLASH_SECTOR_3;
  20. else if(addr<ADDR_FLASH_SECTOR_5)return FLASH_SECTOR_4;
  21. else if(addr<ADDR_FLASH_SECTOR_6)return FLASH_SECTOR_5;
  22. else if(addr<ADDR_FLASH_SECTOR_7)return FLASH_SECTOR_6;
  23. else if(addr<ADDR_FLASH_SECTOR_8)return FLASH_SECTOR_7;
  24. else if(addr<ADDR_FLASH_SECTOR_9)return FLASH_SECTOR_8;
  25. else if(addr<ADDR_FLASH_SECTOR_10)return FLASH_SECTOR_9;
  26. else if(addr<ADDR_FLASH_SECTOR_11)return FLASH_SECTOR_10;
  27. else if(addr<ADDR_FLASH_SECTOR_12)return FLASH_SECTOR_11;
  28. else if(addr<ADDR_FLASH_SECTOR_13)return FLASH_SECTOR_12;
  29. else if(addr<ADDR_FLASH_SECTOR_14)return FLASH_SECTOR_13;
  30. else if(addr<ADDR_FLASH_SECTOR_15)return FLASH_SECTOR_14;
  31. else if(addr<ADDR_FLASH_SECTOR_16)return FLASH_SECTOR_15;
  32. else if(addr<ADDR_FLASH_SECTOR_17)return FLASH_SECTOR_16;
  33. else if(addr<ADDR_FLASH_SECTOR_18)return FLASH_SECTOR_17;
  34. else if(addr<ADDR_FLASH_SECTOR_19)return FLASH_SECTOR_18;
  35. else if(addr<ADDR_FLASH_SECTOR_20)return FLASH_SECTOR_19;
  36. else if(addr<ADDR_FLASH_SECTOR_21)return FLASH_SECTOR_20;
  37. else if(addr<ADDR_FLASH_SECTOR_22)return FLASH_SECTOR_21;
  38. else if(addr<ADDR_FLASH_SECTOR_23)return FLASH_SECTOR_22;
  39. return FLASH_SECTOR_23;
  40. }
  41. //从指定地址开始写入指定长度的数据
  42. //特别注意:因为STM32F7的扇区实在太大,没办法本地保存扇区数据,所以本函数
  43. // 写地址如果非0XFF,那么会先擦除整个扇区且不保存扇区数据.所以
  44. // 写非0XFF的地址,将导致整个扇区数据丢失.建议写之前确保扇区里
  45. // 没有重要数据,最好是整个扇区先擦除了,然后慢慢往后写.
  46. //该函数对OTP区域也有效!可以用来写OTP区!
  47. //OTP区域地址范围:0X1FF0F000~0X1FF0F41F
  48. //WriteAddr:起始地址(此地址必须为4的倍数!!)
  49. //pBuffer:数据指针
  50. //NumToWrite:字(32位)数(就是要写入的32位数据的个数.)
  51. void STMFLASH_Write(u32 WriteAddr,u32 *pBuffer,u32 NumToWrite)
  52. {
  53. // FLASH_EraseInitTypeDef FlashEraseInit;
  54. HAL_StatusTypeDef FlashStatus=HAL_OK;
  55. // u32 SectorError=0;
  56. // u32 addrx=0;
  57. u32 endaddr=0;
  58. if(WriteAddr<STM32_FLASH_BASE||WriteAddr%4)return; //非法地址
  59. HAL_FLASH_Unlock(); //解锁
  60. // addrx=WriteAddr; //写入的起始地址
  61. endaddr=WriteAddr+NumToWrite*4; //写入的结束地址
  62. // if(addrx<0X1FF00000)
  63. // {
  64. // while(addrx<endaddr) //扫清一切障碍.(对非FFFFFFFF的地方,先擦除)
  65. // {
  66. // if(STMFLASH_ReadWord(addrx)!=0XFFFFFFFF)//有非0XFFFFFFFF的地方,要擦除这个扇区
  67. // {
  68. // FlashEraseInit.TypeErase=FLASH_TYPEERASE_SECTORS; //擦除类型,扇区擦除
  69. // FlashEraseInit.Sector=STMFLASH_GetFlashSector(addrx); //要擦除的扇区
  70. // FlashEraseInit.NbSectors=1; //一次只擦除一个扇区
  71. // FlashEraseInit.VoltageRange=FLASH_VOLTAGE_RANGE_3; //电压范围,VCC=2.7~3.6V之间!!
  72. // if(HAL_FLASHEx_Erase(&FlashEraseInit,&SectorError)!=HAL_OK)
  73. // {
  74. // break;//发生错误了
  75. // }
  76. // //SCB_CleanInvalidateDCache(); //清除无效的D-Cache
  77. // }else addrx+=4;
  78. // FLASH_WaitForLastOperation(FLASH_WAITETIME); //等待上次操作完成
  79. // }
  80. // }
  81. // FlashStatus=FLASH_WaitForLastOperation(FLASH_WAITETIME); //等待上次操作完成
  82. if(FlashStatus==HAL_OK)
  83. {
  84. while(WriteAddr<endaddr)//写数据
  85. {
  86. if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,WriteAddr,*pBuffer)!=HAL_OK)//写入数据
  87. {
  88. break; //写入异常
  89. }
  90. WriteAddr+=4;
  91. pBuffer++;
  92. }
  93. }
  94. HAL_FLASH_Lock(); //上锁
  95. }
  96. //从指定地址开始读出指定长度的数据
  97. //ReadAddr:起始地址
  98. //pBuffer:数据指针
  99. //NumToRead:字(32位)数
  100. void STMFLASH_Read(u32 ReadAddr,u32 *pBuffer,u32 NumToRead)
  101. {
  102. u32 i;
  103. for(i=0;i<NumToRead;i++)
  104. {
  105. pBuffer[i]=STMFLASH_ReadWord(ReadAddr);//读取4个字节.
  106. ReadAddr+=4;//偏移4个字节.
  107. }
  108. }
  109. //擦掉0x08040000之后的区域
  110. void ersae_all()
  111. {
  112. printf("擦除Flash中...\r\n");
  113. HAL_FLASH_Unlock();
  114. FLASH_EraseInitTypeDef FlashEraseInit;
  115. u32 SectorError=0;
  116. FlashEraseInit.TypeErase=FLASH_TYPEERASE_SECTORS ; //擦除类型,扇区擦除
  117. FlashEraseInit.Sector=STMFLASH_GetFlashSector(0x08040000); //要擦除的扇区
  118. FlashEraseInit.NbSectors=18; //一次只擦除一个扇区
  119. FlashEraseInit.VoltageRange=FLASH_VOLTAGE_RANGE_3; //电压范围,VCC=2.7~3.6V之间!!
  120. HAL_FLASHEx_Erase(&FlashEraseInit,&SectorError);
  121. HAL_FLASH_Lock();
  122. printf("擦除Flash完成\r\n");
  123. }
  124. void write(u32 WriteAddr,u32 *pBuffer)
  125. {
  126. u32 endaddr=0;
  127. HAL_FLASH_Unlock(); //解锁
  128. //WriteAddr; //写入的起始地址
  129. endaddr=WriteAddr+0x40000; //写入的结束地址
  130. while(WriteAddr<endaddr)//写数据
  131. {
  132. if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,WriteAddr,*pBuffer)!=HAL_OK)//写入数据
  133. {
  134. break; //写入异常
  135. }
  136. WriteAddr+=4;
  137. pBuffer++;
  138. }
  139. HAL_FLASH_Lock(); //上锁
  140. }