STM32
直播中

刘洋

10年用户 1112经验值
擅长:可编程逻辑 嵌入式技术
私信 关注
[问答]

怎样去操作基于STM32F407 HAL库的Flash编程呢

怎样去操作基于STM32F407 HAL库的Flash编程呢?
flash的写入操作是怎样的?


回帖(1)

王媛媛

2021-10-20 09:36:11
  flash的初始化,flash和清除一些flash的异常状态标识
  uint16_t MEM_If_Init_FS(无效)
  {
  HAL_FLASH_Unlock();
  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
  FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
  }
  uint16_t MEM_If_DeInit_FS(无效)
  {
  HAL_FLASH_Lock();
  }
  flash的指令操作
  uint16_t MEM_If_Erase_FS(uint32_t start_Add,uint32_t end_Add)
  {
  /* 用户代码开始 3 */
  uint32_t 用户起始扇区;
  uint32_t 扇区错误;
  FLASH_EraseInitTypeDef pEraseInit;
  /* 解锁 Flash 使能 Flash 控制寄存器访问 *************/
  MEM_If_Init_FS();
  /* 获取开始用户闪存区的扇区 */
  UserStartSector = GetSector(start_Add);
  pEraseInit.TypeErase = TYPEERASE_SECTORS;
  pEraseInit.Sector = UserStartSector;
  pEraseInit.NbSectors = GetSector(end_Add)-UserStartSector+1 ;
  pEraseInit.VoltageRange = VOLTAGE_RANGE_3;
  如果(HAL_FLASHEx_Erase(&pEraseInit, &SectorError) != HAL_OK)
  {
  /* 页面擦除时出错 */
  返回(1);
  }
  返回(USBD_OK);
  /* 用户代码结束 3 */
  }
  注意这里使用GetSector()函数获取的,是一个整型数字(对于F4就是0~11)。
  其中的 NbSectors 是需要清除的扇区的个数。
  下面是获取部门编号的
  我们先按照用户上的手册在u***d_dfu_.h中定义一些文件如果写的领域地址地址
  #define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base @ of Sector 0, 16 KB */
  #define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08004000) /* Base @ of Sector 1, 16 KB */
  #define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08008000) /* Base @ of Sector 2, 16 KB */
  #define ADDR_FLASH_SECTOR_3 ((uint32_t)0x0800C000) /* Base @ of Sector 3, 16 KB */
  #define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08010000) /* Base @ of Sector 4, 64 KB */
  #define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08020000) /* Base @ of Sector 5, 128 KB */
  #define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08040000) /* Base @ of Sector 6, 128 KB */
  #define ADDR_FLASH_SECTOR_7 ((uint32_t)0x08060000) /* Base @ of Sector 7, 128 KB */
  #define ADDR_FLASH_SECTOR_8 ((uint32_t)0x08080000) /* Base @ of Sector 8, 128 KB */
  #define ADDR_FLASH_SECTOR_9 ((uint32_t)0x080A0000) /* Base @ of Sector 9, 128 KB */
  #define ADDR_FLASH_SECTOR_10 ((uint32_t)0x080C0000) /* Base @ of Sector 10, 128 KB */
  #define ADDR_FLASH_SECTOR_11 ((uint32_t)0x080E0000) /* Base @ of Sector 11, 128 KB */
  再在u***d_dfu_if.c文件中添加函数:
  /**
  * @brief 获取给定地址的扇区
  * @param 地址: Flash 地址
  * @retval 给定地址的扇区
  */
  静态 uint32_t GetSector(uint32_t 地址)
  {
  uint32_t 扇区 = 0;
  if((地址《ADDR_FLASH_SECTOR_1) && (地址》= ADDR_FLASH_SECTOR_0))
  {
  扇区 = FLASH_SECTOR_0;
  }
  else if((地址《 ADDR_FLASH_SECTOR_2) && (地址 》= ADDR_FLASH_SECTOR_1))
  {
  扇区 = FLASH_SECTOR_1;
  }
  else if((地址《 ADDR_FLASH_SECTOR_3) && (地址 》= ADDR_FLASH_SECTOR_2))
  {
  扇区 = FLASH_SECTOR_2;
  }
  else if((地址《 ADDR_FLASH_SECTOR_4) && (地址 》= ADDR_FLASH_SECTOR_3))
  {
  扇区 = FLASH_SECTOR_3;
  }
  else if((地址《 ADDR_FLASH_SECTOR_5) && (地址 》= ADDR_FLASH_SECTOR_4))
  {
  扇区 = FLASH_SECTOR_4;
  }
  else if((地址《 ADDR_FLASH_SECTOR_6) && (地址 》= ADDR_FLASH_SECTOR_5))
  {
  扇区 = FLASH_SECTOR_5;
  }
  else if((地址《 ADDR_FLASH_SECTOR_7) && (地址 》= ADDR_FLASH_SECTOR_6))
  {
  扇区 = FLASH_SECTOR_6;
  }
  else if((地址《 ADDR_FLASH_SECTOR_8) && (地址 》= ADDR_FLASH_SECTOR_7))
  {
  扇区 = FLASH_SECTOR_7;
  }
  else if((地址《 ADDR_FLASH_SECTOR_9) && (地址 》= ADDR_FLASH_SECTOR_8))
  {
  扇区 = FLASH_SECTOR_8;
  }
  else if((地址《 ADDR_FLASH_SECTOR_10) && (地址 》= ADDR_FLASH_SECTOR_9))
  {
  扇区 = FLASH_SECTOR_9;
  }
  else if((地址《 ADDR_FLASH_SECTOR_11) && (地址 》= ADDR_FLASH_SECTOR_10))
  {
  扇区 = FLASH_SECTOR_10;
  }
  别的
  {
  扇区 = FLASH_SECTOR_11;
  }
  返回扇区;
  }
  flash的写入操作
  uint16_t MEM_If_Write_FS(uint8_t *src, uint8_t *dest, uint32_t Len)
  {
  /* 用户代码开始 3 */
  uint32_t i = 0;
  对于(i = 0; 我《伦;i+=4)
  {
  /* 设备电压范围应该是[2.7V 到 3.6V],操作将
  按字节完成 */
  if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, (uint32_t)(dest+i), *(uint32_t*)(src+i)) == HAL_OK)
  {
  /* 检查写入的值 */
  if(*(uint32_t *)(src + i) != *(uint32_t*)(dest+i))
  {
  /* Flash 内容与 SRAM 内容不匹配 */
  返回2;
  }
  }
  别的
  {
  /* 在闪存中写入数据时发生错误 */
  返回 1;
  }
  }
  返回(HAL_OK);
  /* 用户代码结束 3 */
  }
  flash的读出操作
  uint8_t *MEM_If_Read_FS (uint8_t *src, uint8_t *dest, uint32_t Len)
  {
  /* 返回一个有效地址以避免硬故障 */
  /* 用户代码开始 4 */
  uint32_t i = 0;
  uint8_t *psrc = src;
  对于(i = 0; 我《伦;我++)
  {
  dest[i] = *psrc++;
  }
  返回 HAL_OK;
  /* 用户代码结束 4 */
  }
举报

更多回帖

发帖
×
20
完善资料,
赚取积分