STM32 flash

Flash 有以下几个寄存器,在地址0x40022000开始
在这里插入图片描述
上锁:设置 CR的bit8位为1
解锁:往KEYR连续写入KEY1,KEY2

在规格书上看到的page0 page1…,翻译成中文是 “页”
对于小容量的STM32,一页是1K字节,占地址是0x03FF(0xFF是256,0x3FF=4*0xFF=1024);大容量的STM32一个页是2K字节,为什么要清楚这个呢。因为flash的擦除是按 页 来的,一次至少擦除一个 页。如果想擦除某个地址,必须计算出该地址在的那个 页。另外写入之前必须先擦除,那么如果只写入一个字节,则需要先读出该页的其它内容,然后擦除该页,再把读出的其它内容写回去。

  //在stm32f1xx_hal_flash_ex.h文件中,根据不同型号,定义有页的大小
#if defined(STM32F101x6) || defined(STM32F102x6) || defined(STM32F103x6) ||   defined(STM32F100xB) || defined(STM32F101xB) || defined(STM32F102xB) || defined(STM32F103xB)
#define FLASH_PAGE_SIZE          ((uint32_t)0x400)
#endif /
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F103xE) ||  \ defined(STM32F101xG) || defined(STM32F103xG) ||    defined(STM32F105xC) || defined(STM32F107xC)
#define FLASH_PAGE_SIZE          ((uint32_t)0x800)
#endif /

擦除某个地址之后的 所有页

uint32_t FLASH_If_Erase(uint32_t start)
{
  uint32_t NbrOfPages = 0;
  uint32_t PageError = 0;
  FLASH_EraseInitTypeDef pEraseInit;
  HAL_StatusTypeDef status = HAL_OK;
      /* Unlock the Flash to enable the flash control register access *************/ 
  HAL_FLASH_Unlock();
      /* Get the sector where start the user flash area */
      
  NbrOfPages = (USER_FLASH_END_ADDRESS - start)/FLASH_PAGE_SIZE;//计算页数
      pEraseInit.TypeErase = FLASH_TYPEERASE_PAGES;//选择按页擦除 或 全部擦除
  pEraseInit.PageAddress = start;//开始地址
  pEraseInit.Banks = FLASH_BANK_1;
  pEraseInit.NbPages = NbrOfPages;//页数量
  status = HAL_FLASHEx_Erase(&pEraseInit, &PageError);//调用库函数擦除

  HAL_FLASH_Lock();
  if (status != HAL_OK)
  {
    return FLASHIF_ERASEKO;
  }
  return FLASHIF_OK;
}

按页擦除的程序, 如果要擦除多面,用下面的for语句循环调用FLASH_PageErase(address)

 for(address = pEraseInit->PageAddress;  address < (pEraseInit->PageAddress + (pEraseInit->NbPages)*FLASH_PAGE_SIZE); address += FLASH_PAGE_SIZE)

在这里插入图片描述
整个flash都擦除的更简单一点

static void FLASH_MassErase(uint32_t Banks)
{
    /*Only bank1 will be erased*/
    SET_BIT(FLASH->CR, FLASH_CR_MER);   //置CR的MER=1
    SET_BIT(FLASH->CR, FLASH_CR_STRT);  //置CR的STRT=1开始擦除, 跳出后等待BSY=0,然后把MER清0
}

写入数据流程:CR的PG=1---->写入数据到指定地址------->返回上一级后等待BSY=0------->把PG清0,一次只写入半字(2个字节),循环调用可写入多字节。

void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data)
{
    /* Proceed to program the new data */
    SET_BIT(FLASH->CR, FLASH_CR_PG);
  /* Write data in the address */
  *(__IO uint16_t*)Address = Data;
}

查看是否有被保护的页:
1、解锁后----->读出WRPR寄存器------>读出OBR中的RDPRT位---->读出OBR中的用户配置位bit2-5------判断WRPR寄存器中的位,为0的表示对应的页被保护了,bit0–0-3页,bit1—4-7页(不同型号1bit对应的页数是不一样的)…

设置保护或解除保护
1、读取当前的保护状态:读取WRPR—>读取OBR中的RDPRT位,表示保护等级(0级和1级)—>读出OBR中的用户配置位bit2-5—>解锁flash(如果CR的lock位为1,写KEY1和KEY2到KEYR解锁)----->解锁OPT(如果CR的OPTWRE位为1,写OPTKEY1和OPTKEY2到OPTKEYR解锁)----->擦除所有OPT选项字-------->写入新的选项字。

擦除所有OPT选项字:
读取OBR(0x4002 201C)中的RDPRT位,该位表示读保护等级(0级未保护和1级保护)----->置1 CR的OPTER位------>置1 CR的STRT位------>等待BSY=0------>清0 CR的OPTER位------->把读保护等级RDPRT写回去(等待BSY=0----->置1 CR 的OPTPG-------->把读保护等级写入RDP寄存器0x1FFF F8000-------->等待BSY=0------->清0 CR的OPTPG)

写入新选项字:
如果是要设置写保护,置1 CR的OPTPG---->(设置这4个字节寄存器WRP0…WRP3 ,小容量的只有WRP0, 这是16位寄存器,低8bit表示被设备保护的32页,即1bit设置4个页,对应的位为1表示未保护,为0则表示保护)----->清0 CR的OPTPG-------->如果是要设置不保护------>则WRP0…都写入0xFFFF---------->设置完写保护状态后,设置读保护状态-------设置读保护等级为0----->设置用户配置----->设置用户数据

更详细解说,参考https://www.cnblogs.com/pertor/p/9484663.html

另外可以参考:这里说到块跟页
http://blog.chinaunix.net/uid-20617446-id-3847242.html

### 解析STM32 FLASH_PageErase函数未定义的原因 当遇到`FLASH_PageErase`函数未定义的情况时,通常是由于缺少必要的库文件或配置不正确所引起的。具体来说,可能是某些源文件未能被正确引入到当前工程项目中[^5]。 ### 实施解决方案 为了有效解决问题,建议按照以下方式操作: #### 检查并补充缺失的源文件 确认项目中的`FWLib`或其他相关目录下是否存在所有必需的支持文件。如果发现有遗漏,则应立即将其加入至工程结构内。例如,在处理Flash擦除功能时,确保包含了实现该特性的`.c`文件。 ```cpp // 示例:假设需要添加stm_flash.c作为支持文件之一 #include "stm_flash.h" void example_function(void){ // 使用FLASH_PageErase前需保证已导入对应实现代码 } ``` #### 验证编译器设置与链接选项 除了检查源码外,还需仔细核对编译环境下的各项参数设定,特别是对于像VSCode这样的集成开发环境中,可能还需要额外调整一些构建工具链的相关属性以适应特定硬件平台的需求[^1]。 #### 审视头文件包含情况 确保所有的头文件都已被适当引用,并且路径指向准确无误。特别是在涉及HAL库的情况下,务必开启相应模块的功能开关(如通过取消注释的形式激活),以便使能所需特性及其关联接口声明[^3]。 ```c /* stm32fxxx_hal_conf.h */ #define HAL_FLASH_MODULE_ENABLED /* 如果使用了Flash API则不应省略此行 */ #ifdef HAL_FLASH_MODULE_ENABLED #include "stm32fxxx_hal_flash.h" #endif ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值