历史上的今天
返回首页

历史上的今天

今天是:2024年10月29日(星期二)

正在发生

2021年10月29日 | stm32专题二十八:读写内部Flash

2021-10-29 来源:eefocus

内部Flash       

       STM32芯片内部有一个FLASH存储器,主要用于存储代码。我们在电脑上编写好应用程序后,使用下载器把编译后的代码文件烧录到该内部FLASH中,由于FLASH存储器的内容在掉电后不会丢失,芯片重新上电复位后,内核可从内部FLASH中加载代码并运行。


       除了使用外部的工具(如下载器)读写内部FLASH外,STM32芯片在运行的时候,也能对自身的内部FLASH进行读写,因此,若内部FLASH存储了应用程序后还有剩余的空间,我们可以把它像外部SPI-FLASH那样利用起来,存储一些程序运行时产生的需要掉电保存的数据。


       由于访问内部FLASH的速度要比外部的SPI-FLASH快得多,所以在紧急状态下常常会使用内部FLASH存储关键记录;为了防止应用程序被抄袭,有的应用会禁止读写内部FLASH中的内容,或者在第一次运行时计算加密信息并记录到某些区域,然后删除自身的部分加密代码,这些应用都涉及到内部FLASH的操作。


如图所示为内部Flash结构(大容量):

主要功能描述:


主存储器中保存了我们烧写到Flash中的程序;

启动程序代码(系统存储区):是用户不能访问的区域,它在芯片出厂时已经固化了启动代码,它负责实现串口、USB以及CAN等ISP烧录功能;

用户选择字节(选项字节):选项字节用于配置FLASH的读写保护、待机/停机复位、软件/硬件看门狗等功能;

主存储器:


       通常我们说STM32内部FLASH的时候,都是指这个主存储器区域,它是存储用户应用程序的空间,芯片型号说明中的256K FLASH、512K FLASH都是指这个区域的大小。


        主存储器分为256页,每页大小为2KB,共512KB。这个分页的概念,实质就是FLASH存储器的扇区,与其它FLASH一样,在写入数据前,要先按页(扇区)擦除。


对内部Flash的写入过程:


1 解锁:


闪存编程手册说明:

操作过程:

操作的寄存器:

2 页擦除:


闪存编程手册说明:

执行流程:

具体的实现过程:

涉及到的寄存器:

还有不常使用的全片擦除(防止破解):

3 写入数据:


擦除完毕后即可写入数据,写入数据的过程并不是仅仅使用指针向地址赋值,赋值前还还需要配置一系列的寄存器,步骤如下:


检查 FLASH_SR 中的 BSY 位,以确认当前未执行任何其它的内部 Flash 操作;

将 FLASH_CR 寄存器中的 “激活编程寄存器位 PG” 置 1;

向指定的 FLASH 存储器地址执行数据写入操作,每次只能以 16位的方式写入;

等待 BSY 位被清零时,表示写入完成;

闪存编程手册中的描述:

操作内部Flash的库函数


解锁 + 上锁


void FLASH_Unlock(void)

{

  /* Authorize the FPEC of Bank1 Access */

  FLASH->KEYR = FLASH_KEY1;

  FLASH->KEYR = FLASH_KEY2;

}

void FLASH_Lock(void)

{

  /* Set the Lock Bit to lock the FPEC and the CR of  Bank1 */

  FLASH->CR |= CR_LOCK_Set;

}

擦除扇区


/**

  * @brief  Erases a specified FLASH page.

  * @note   This function can be used for all STM32F10x devices.

  * @param  Page_Address: The page address to be erased.

  * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,

  *         FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.

  */

FLASH_Status FLASH_ErasePage(uint32_t Page_Address)

{

  FLASH_Status status = FLASH_COMPLETE;

 

  /* 等待上一次操作完成 */

  status = FLASH_WaitForLastOperation(EraseTimeout);

  

  if(status == FLASH_COMPLETE)

  { 

    /* 准备擦除页 */

    FLASH->CR|= CR_PER_Set;

    FLASH->AR = Page_Address; 

    FLASH->CR|= CR_STRT_Set;

    

    /* 等待操作完成 */

    status = FLASH_WaitForLastOperation(EraseTimeout);

    

    /* 禁用页擦除 */

    FLASH->CR &= CR_PER_Reset;

  }

 

  return status;

}

闪存编程(一次必须写入16位)


/**

  * @brief  Programs a half word at a specified address.

  * @note   This function can be used for all STM32F10x devices.

  * @param  Address: specifies the address to be programmed.

  * @param  Data: specifies the data to be programmed.

  * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,

  *         FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. 

  */

FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data)

{

  FLASH_Status status = FLASH_COMPLETE;

 

  /* Wait for last operation to be completed */

  status = FLASH_WaitForLastOperation(ProgramTimeout);

  

  if(status == FLASH_COMPLETE)

  {

    /* if the previous operation is completed, proceed to program the new data */

    FLASH->CR |= CR_PG_Set;

  

    /* 把地址参数强制转换为指针,再通过指针操作写入数据 */

    *(__IO uint16_t*)Address = Data;

 

    /* Wait for last operation to be completed */

    status = FLASH_WaitForLastOperation(ProgramTimeout);

    

    /* Disable the PG Bit */

    FLASH->CR &= CR_PG_Reset;

  } 

  

  /* Return the Program Status */

  return status;

}

实验:读写内部Flash


/**

  * @brief  InternalFlash_Test,对内部FLASH进行读写测试

  * @param  None

  * @retval None

  */

int InternalFlash_Test(void)

{

uint32_t EraseCounter = 0x00; //记录要擦除多少页

uint32_t Address = 0x00; //记录写入的地址

uint32_t Data = 0x3210ABCD; //记录写入的数据

uint32_t NbrOfPage = 0x00; //记录写入多少页

FLASH_Status FLASHStatus = FLASH_COMPLETE; //记录每次擦除的结果

TestStatus MemoryProgramStatus = PASSED;//记录整个测试结果

 

  /* 解锁 */

  FLASH_Unlock();

 

  /* 计算要擦除多少页 */

  NbrOfPage = (WRITE_END_ADDR - WRITE_START_ADDR) / FLASH_PAGE_SIZE;

 

  /* 清空所有标志位 */

  FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);

 

  /* 按页擦除*/

  for(EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++)

  {

    FLASHStatus = FLASH_ErasePage(WRITE_START_ADDR + (FLASH_PAGE_SIZE * EraseCounter));

  

}

  

  /* 向内部FLASH写入数据 */

  Address = WRITE_START_ADDR;

 

  while((Address < WRITE_END_ADDR) && (FLASHStatus == FLASH_COMPLETE))

  {

    FLASHStatus = FLASH_ProgramWord(Address, Data);

    Address = Address + 4;

  }

 

  FLASH_Lock();

  

  /* 检查写入的数据是否正确 */

  Address = WRITE_START_ADDR;

 

  while((Address < WRITE_END_ADDR) && (MemoryProgramStatus != FAILED))

  {

    if((*(__IO uint32_t*) Address) != Data)

    {

      MemoryProgramStatus = FAILED;

    }

    Address += 4;

  }

return MemoryProgramStatus;

}


主要流程:

实验结果:

推荐阅读

史海拾趣

Chip Supply Micro Devices公司的发展小趣事

为了进一步扩大市场份额,Chip Supply Micro Devices制定了国际化战略。公司积极开拓海外市场,通过参加国际电子展会、建立海外销售网络等方式,将产品推向全球。同时,公司还针对不同国家和地区的市场需求,推出了定制化的产品解决方案。这些努力使得Chip Supply Micro Devices在国际市场上获得了良好的口碑和业绩。

Eurohm Resistors公司的发展小趣事

随着市场的不断扩张和竞争的加剧,Eurohm Resistors始终坚持品质至上的原则。公司建立了严格的质量控制体系,从原材料采购到生产流程,再到成品检验,每一个环节都严格把关。这种对品质的坚守不仅赢得了客户的信任,也为公司赢得了良好的口碑。

AiT Semiconductor Inc公司的发展小趣事

在半导体行业,技术创新是企业持续发展的关键。AiT公司深知这一点,因此始终将创新作为公司的核心竞争力。他们投入大量资金和资源用于研发,不断推出具有创新性和领先性的半导体产品。同时,公司还积极与高校、科研机构等合作,共同开展技术研发和人才培养工作。这些创新举措使得AiT公司在行业中始终保持领先地位。

AXTAL公司的发展小趣事

自成立以来,AXTAL公司一直致力于提升产品的技术和品质。公司凭借完善的质量管理体系(QMS)确保产品的高质量和可靠性。在产品设计阶段,AXTAL应用了受控设计流程,并在客户应用程序中进行了大量验证步骤和最终验证。同时,公司还拥有记录良好的制造流程过程控制系统,通过大量的在线测试、检查和筛选,确保每一件产品都符合高标准的质量要求。

Consolidated Wire公司的发展小趣事

在电子行业的早期,Consolidated Wire公司以其出色的技术研发能力崭露头角。公司投入大量资源研发新型导电材料,成功推出了一种具有更高导电性能和更低电阻的新型线材。这一技术突破不仅提升了电子设备的性能,还降低了能耗,赢得了市场的广泛认可。随着新型线材的普及,Consolidated Wire公司的业务规模迅速扩大,逐渐在电子线材市场占据了领先地位。

bb-smartworx公司的发展小趣事

在竞争激烈的电子行业中,Consolidated Wire公司始终坚持品质至上的原则。公司建立了严格的质量管理体系,从原材料采购到生产过程控制,再到产品出厂检验,每一个环节都严格把关。这种对品质的执着追求使得Consolidated Wire公司的产品赢得了客户的信任和好评。许多知名企业都成为了公司的合作伙伴,共同推动电子行业的发展。

问答坊 | AI 解惑

A/D高速采集模拟信号的阈值设定

来源:单片机及嵌入式系统应用  作者:北京理工大学 李大国 张庆明A/D转换接口电路是数据采集系统前向通道中的一个环节,它的作用是将模拟信号转换成可供计算机处理的数字信号,是一般控制系统中不可缺少的环节之一。人们有时需要对A/D转换的 ...…

查看全部问答>

FPGA防拷贝技术讨论

众所周知,用FPGA开发产品有好多优势,对于主流SRAM结构的FPGA在防拷贝,盗版方面,不安全甚至非常脆弱,是因为一旦系统上电,盗版者就能轻而易举地获取FPGA的位流。   Altera从StratixII只是在高端器件中对于配置比特流提供了128bit AE ...…

查看全部问答>

关于ALTIUM DESIGNER的snippets选项

1.右键单击的时候无snippets选项 2.在右下角system选项卡中选中snippets后,creat snippet from selection,无反应。 请指教。…

查看全部问答>

合众达网站几年里的精华问答

合众达网站几年里的精华问答…

查看全部问答>

各位高手帮帮忙啊!电子密码锁

课程设计弄要求做电子密码锁,可我做的时不能改密码和断电保护的。老师说不合格!    高手们帮忙传个电路图和程序到我的邮箱里~   gaoyabei1985@163.com 万分感谢啊!…

查看全部问答>

空调遥控器采用的什么红外编码协议?

有人知道 空调采用的什么协议不? 我通过测试,也不是NEC的和RC-5的协议 用示波器查看,波形很乱,根本就没有规律 我用软件测试,0.1ms采集一次接口管IO口的电平状态,得到字节数据,然后再转换成波形, 我分析得到的波形,也不是规律的 大部分 ...…

查看全部问答>

做个仿POS的设备

手持式设备的要求 1.        内置打印机,有外置打印机接口,可使用外部打印机快速打印 2.        支持MODEM 电话拨号连接 3.        有ETHernet 网络接口 4.      ...…

查看全部问答>

看门狗问题请教

                                 STM32F101C8T6芯片,没有打开看门狗时,JLINK仿真器仿真一直正常,但是今天增加了看门狗看门狗后(IWDG),第一次程 ...…

查看全部问答>

保持时间为负怎样理解

保持时间为什么负值,是时钟频率太高吗? 对了,在ALTAER的提供的DATASHEET上可以看到保持时间最小位0。 从保持时间的定义来讲,就是这个数据不需要保持时间,只需要建立时间,D触发器就可以 正确采样LE.  不知到,这个D触发器怎样做到这 ...…

查看全部问答>

从CC2530 到 CC2530+CC2591

从CC2530 到 CC2530+CC2591 程序中除了将 #define xHAL_PA_LNA 改为 #define HAL_PA_LNA   还有什么设置?…

查看全部问答>