soft_flash.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #include "main.h"
  2. #include "soft_flash.h"
  3. #include <string.h>
  4. #include "soft_crc.h"
  5. #include "stm32f4xx_hal_flash_ex.h"
  6. extern UART_HandleTypeDef huart2;
  7. uint32_t sectStartAddr[12]=
  8. {
  9. 0x08000000,//0
  10. 0x08004000,//1
  11. 0x08008000,//2
  12. 0x0800c000,//3
  13. 0x08010000,//4
  14. 0x08020000,//5
  15. 0x08040000,//6
  16. 0x08060000, //7
  17. 0x08080000, //8
  18. 0x080A0000, //9
  19. 0x080C0000, //10
  20. 0x080E0000, //11
  21. };
  22. int GetSectorFromAddress(uint32_t address)
  23. {
  24. int sect = 0;
  25. if( address < 0x08000000 || address > 0x08100000 )
  26. return -1;
  27. for( int i=0; i<8; i++ )
  28. {
  29. if( address >= sectStartAddr[i] && address < sectStartAddr[i+1] )
  30. {
  31. sect = i;
  32. break;
  33. }
  34. }
  35. return sect;
  36. }
  37. //FLASH写
  38. uint32_t Flash_WriteData(uint32_t addr, uint16_t *data, uint16_t Size)
  39. {
  40. static int8_t cur_sector = -1;
  41. uint8_t tar_sector = 0;
  42. __disable_irq();
  43. HAL_FLASH_Unlock();
  44. __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
  45. FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);//清除一些错误标志
  46. //是否要擦扇区
  47. tar_sector = GetSectorFromAddress(addr);//获取地址所在的扇区
  48. if(tar_sector != cur_sector)
  49. {
  50. FLASH_Erase_Sector(tar_sector,FLASH_VOLTAGE_RANGE_3);//擦除指定的闪存扇区(0~11)
  51. cur_sector = tar_sector;
  52. }
  53. uint16_t TempBuf = 0;
  54. for (uint16_t i = 0; i < Size; i++)
  55. {
  56. TempBuf = *(data + i);
  57. HAL_StatusTypeDef a = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, addr + i * 2, TempBuf);
  58. if (a != HAL_OK)
  59. {
  60. HAL_FLASH_Lock();
  61. __enable_irq();
  62. return WRITE_FAIL;
  63. }
  64. }
  65. HAL_FLASH_Lock();
  66. __enable_irq();
  67. return WRITE_SUCCESS;
  68. }
  69. bool wirte_update_flag()
  70. {
  71. uint8_t sect = 0;
  72. HAL_StatusTypeDef status;
  73. __disable_irq();
  74. HAL_FLASH_Unlock();
  75. __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
  76. FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);//清除一些错误标志
  77. sect = GetSectorFromAddress(FLASH_UPDATE_ADDR);//获取地址所在的扇区
  78. FLASH_Erase_Sector(sect,FLASH_VOLTAGE_RANGE_3);//擦除指定的闪存扇区(0~11)
  79. status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, FLASH_UPDATE_ADDR, 0XF);
  80. HAL_FLASH_Lock();
  81. __enable_irq();
  82. if(status == HAL_OK)
  83. return true;
  84. else
  85. return false;
  86. }
  87. //FLASH读地址
  88. uint16_t ReadFlashNBtye(uint32_t ReadAddress, uint16_t *ReadBuf, int32_t ReadNum)
  89. {
  90. int DataNum = 0;
  91. uint16_t up_flag = 0;
  92. *ReadBuf = *(__IO uint16_t *)ReadAddress;
  93. up_flag = *ReadBuf;
  94. DataNum++;
  95. return up_flag;
  96. }
  97. //读取标志位
  98. uint32_t flash_read_updata_flag(void)
  99. {
  100. uint16_t temp_buff = 0;
  101. uint32_t Address = 0;
  102. temp_buff = ReadFlashNBtye(FLASH_UPDATE_ADDR, (uint16_t *)&Address, 1);
  103. return temp_buff;
  104. }