历史上的今天
返回首页

历史上的今天

今天是:2024年08月23日(星期五)

正在发生

2021年08月23日 | 玩转STM32CubeMX | STM32内部FLASH

2021-08-23 来源:eefocus

1.内部FLASH简介

之前的文章中介绍过STM32F1利用SPI与外部FLASH(W25QXX芯片)通讯的例程,本例程将介绍STM32F1的内部FLASH,通过内部FLASH实现数据读写操作。


不同型号的STM32,其FLASH容量也有所不同,最小的只有16K字节,最大的则达到了1024K字节。此处我们使用的是STM32F103ZET6,其FLASH容量为512K字节,属于大容量产品,大容量产品的闪存模块组织图如下图示

STM32F1的闪存模块由:主存储器、信息块和闪存存储器接口寄存器3部分组成


*主存储器:用来存放代码和数据常量,起始地址是0x08000000,BOOT0和BOOT1都接GND时,就是从该起始地址运行代码的

 

*信息块:分为2个小部分,启动程序代码是用来存储ST自带的启动程序,用于串口下载代码,BOOT0接3.3V,BOOT1接GND时,运行的就是这部分代码;选择字节则一般用于配置写保护、读保护等功能

 

*闪存存储器接口寄存器:用于控制闪存读写等,是整个闪存模块的控制机构


对主存储器和信息块的写入由内嵌的闪存编程/擦除控制器(FPEC)管理:编程与擦除的高电压由内部产生。在执行闪存写操作时,任何对闪存的读操作都会锁住总线,在写操作完成后读操作才能正确地进行,即在进行写或擦除操作时,不能进行代码或数据的读取操作。


下面介绍闪存的读取、编程和擦除:

⏩ 闪存的读取

内置闪存模块可以在通用地址空间直接寻址,任何32位数据的读操作都能访问闪存模块的内容并得到相应的数据。


例如,要从地址addr,读取一个半字,可通过如下语句读取:

data = *(__IO uint16_t*)addr

将addr强制转换为vu16指针,然后取该指针所指向的地址的值,即得到了addr地址的值


⏩ 闪存的编程
STM32的闪存编程是由FPEC(闪存编程和擦除控制器)模块处理的,这个模块包含7个32位寄存器,它们分别是:


- FPEC键寄存器(FLASH_KEYR)


- 选择字节键寄存器(FLASH_OPTKEYR)


- 闪存控制寄存器(FLASH_CR)


- 闪存状态寄存器(FLASH_SR)


- 闪存地址寄存器(FLASH_AR)


- 选择字节寄存器(FLASH_OBR)


- 写保护寄存器(FLASH_WRPR)


其中FPEC键寄存器共有3中键值:
PDPRT=0x000000A5; KEY1=0x45670123; KEY2=0xCDEF89AB
STM32复位后,FPEC模块是被保护的,不能写入FLASH_CR寄存器;通过写入特定的序列到FLASH_KEYR寄存器可以打开FPEC模块(即写入KEY1和KEY2),只有在写保护被解除后,才能操作相关寄存器。


闪存编程过程如下图所示:

⏩ 闪存的擦除
闪存编程的时候,要先判断其写入地址的FLASH是被擦除了的(也就是其值必须是0xFFFF),否则无法写入。闪存擦除分为页擦除和整片擦除。


闪存页擦除过程如下图示:

官方固件HAL库FLASH操作的几个常见函数:


2.硬件设计

D1指示灯用来提示系统运行状态,K_UP按键用来控制FLASH的数据写入,K_DOWN按键用来控制FLASH的数据读取,数据的写入与读取信息通过串口1打印出来


*指示灯D1

 

*USART1串口

 

*STM32F1内部FLASH

 

*K_UP和K_DOWN按键


3.软件设计

3.1 STM32CubeMX设置

➡️ RCC设置外接HSE,时钟设置为72M

➡️ PC0设置为GPIO推挽输出模式、上拉、高速、默认输出电平为高电平

➡️ USART1选择为异步通讯方式,波特率设置为115200Bits/s,传输数据长度为8Bit,无奇偶校验,1位停止位

➡️ PA0设置为GPIO输入模式、下拉模式;PE3设置为GPIO输入模式、上拉模式

➡️输入工程名,选择路径(不要有中文),选择MDK-ARM V5;勾选Generated periphera initialization as a pair of ‘.c/.h’ files per IP ;点击GENERATE CODE,生成工程代码


3.2 MDK-ARM软件编程

➡️ 创建按键驱动文件key.c 和相关头文件key.h,驱动代码参考按键输入例程

➡️ 创建FLASH驱动文件stmflash.c 和相关头文件stmflash.h,这里仅介绍几个重要的函数,工程源文件下载方式见文末介绍


//读取指定地址的半字

uint16_t STMFLASH_ReadHalfWord(uint32_t faddr){

  return *(__IO uint16_t*)faddr; 

}

//不检查的写入

void STMFLASH_Write_NoCheck(uint32_t WriteAddr,uint16_t *pBuffer,uint16_t NumToWrite){  

  uint16_t i;

  for(i=0;i    HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,WriteAddr,pBuffer[i]);

    WriteAddr+=2;//一个地址对应8bits,写入半字,所以地址加2

  }  


//FLASH写函数比较复杂,详细代码请下载源文件查阅

void STMFLASH_Write(uint32_t WriteAddr,uint16_t *pBuffer,uint16_t NumToWrite)


void STMFLASH_Read(uint32_t ReadAddr,uint16_t *pBuffer,uint16_t NumToRead){

  uint16_t i;

  for(i=0;i    pBuffer[i]=STMFLASH_ReadHalfWord(ReadAddr); //读取2个字节

    ReadAddr+=2;//偏移2个字节

  }

}


➡️ 在main.c文件下编写STM32 flash测试代码


/* USER CODE BEGIN PV */

const uint8_t Text_Buf[] = {"STM32F103ZET6 FLASH TEST"};

#define TEXTSIZE sizeof(Text_Buf)

//设置FLASH保存地址(要大于FLASH起始地址)

#define FLASH_SAVE_ADDR 0x08070000

/* USER CODE END PV */

int main(void){

  /* USER CODE BEGIN 1 */

  uint8_t key;

  uint8_t Read_Buf[TEXTSIZE];

  /* USER CODE END 1 */

  HAL_Init();

  SystemClock_Config();

  MX_GPIO_Init();

  MX_USART1_UART_Init();

  /* USER CODE BEGIN 2 */

  printf("STM32 Flash Test...rn");

  /* USER CODE END 2 */

  while (1){

    key = KEY_Scan(0);

    if(key == KEY_UP_PRES){

      STMFLASH_Write(FLASH_SAVE_ADDR,(uint16_t *)Text_Buf,TEXTSIZE);

      printf("FLASH Write : %srn",Text_Buf);

    }

    if(key == KEY_DOWN_PRES){

      STMFLASH_Read(FLASH_SAVE_ADDR,(uint16_t *)Read_Buf,TEXTSIZE);

      printf("FLASH Read : %srn",Read_Buf);

    }

    HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);

    HAL_Delay(200);

  }

}


4.下载验证

编译无误下载到开发板后,可以看到D1指示灯不断闪烁,当按下K_UP按键后数据写入到FLASH内,当按下K_DOWN按键后将写入的数据读取出来,同时串口打印出相应信息

推荐阅读

史海拾趣

Chino-Excel公司的发展小趣事

面对日益严峻的环境问题,Chino-Excel公司积极倡导环保理念,将绿色生产贯穿于整个产业链。公司采用环保材料和节能技术,降低产品生产和运营过程中的能耗和排放。同时,公司还积极参与环保公益活动,推动整个行业向更加环保、可持续的方向发展。

Dailywell Electronics Co Ltd公司的发展小趣事

随着公司实力的不断增强和业务的不断扩展,德利威电子开始实施全球化战略。2002年,公司成立了珠海富鼎厂,正式将东莞的电子产能进行移转。这一举措不仅进一步提升了公司的生产能力和产品品质,也为其进一步拓展国际市场提供了有力支持。此外,公司还在2003年和2006年分别成立了中国东莞办事处和北京办事处,进一步加强了其在中国市场的布局和服务能力。通过这些举措的实施,德利威电子逐步实现了从单一市场向全球市场的转变。

以上五个故事简要概述了德利威电子股份有限公司在电子行业中的发展历程和关键节点。这些故事不仅展示了公司的成长轨迹和实力提升过程,也反映了其在技术创新、品质管理、国际化布局等方面的努力和成就。

BLACK&DECKER公司的发展小趣事

BLACK&DECKER一直致力于产品革新和专利申请。1914年,公司为世界第一台配有枪式手柄、扳机开关和通用马达的便携式手电钻申请了专利。这一发明极大地提高了工作效率,并在市场上取得了巨大的成功。此后,BLACK&DECKER不断推出创新产品,如1946年发明的世界上第一台专为家用消费者设计的便携式电钻,以及后续的电动篱笆剪、全绝缘电钻等一系列重要发明。

强盛电子(AEC)公司的发展小趣事

随着环保意识的日益增强,AEC积极响应国家绿色发展的号召,将环保理念融入企业的日常运营中。公司投入大量资金进行环保技术的研发和应用,推动生产过程的绿色化、低碳化。同时,AEC还积极参与社会公益活动,为保护环境、促进可持续发展贡献了自己的力量。

ATOP_Technologies公司的发展小趣事

随着产品线的不断丰富和技术实力的提升,ATOP Technologies开始将目光投向更广阔的市场。公司积极参与国内外各类行业展会和交流活动,加强与同行和客户的交流与合作。同时,ATOP Technologies还积极开展国际合作,与多个国家的知名企业建立了战略合作关系,共同推动工业自动化领域的发展。

ELDECO公司的发展小趣事

随着环保意识的不断提高,ELDECO公司积极响应国家号召,将绿色环保理念融入产品设计和生产过程中。公司采用环保材料和节能技术制造ELD产品,减少了对环境的污染和能源消耗。同时,公司还推广绿色出行理念,鼓励运输企业采用更环保的运输方式。通过这些措施,ELDECO公司不仅提高了企业的社会责任感,还为推动绿色交通发展做出了积极贡献。

问答坊 | AI 解惑

LED驱动mos推荐

尚晶推荐LED驱动用MOS 管 DTS2306;DTS3400…

查看全部问答>

德州仪器达芬奇五年之路七宗罪,嵌入式处理器架构之争决战2012(三)

2008年,注定是不平凡的一年。 TI或许已经意识到了在中国这样一个神奇的土地上,有这样一个潜规则,那就是只有硬件是可以卖钱的,硬件上跑的所有东西你都要送我。于是TI开始做出这样一个决定,Linux内核维护从以MonvtaVista为主树转移到以自己维护 ...…

查看全部问答>

wince 挂起后, 闹铃

现在是想在 wince 挂起后,待机后, 自已写的闹铃程序不受影响,到达设定的时候时,还能正常响铃... 大家帮忙..谢谢..…

查看全部问答>

windows ce如何与WINDOWS xp联网

  我是刚接触使用WINDOWS ce的新手,我的要求是XP如何与WINDOWS CE通过交换机连接,我现在可以在XP的电脑上PING通WINDOWS CE电脑上的IP,我需要怎么做才可以看到WINDOWS CE上的数据.因为我太需要WINDOWS ce上的数据文件,   麻烦 ...…

查看全部问答>

基于AD9288/DSP的数字图像采集处理

首先谢谢EEWORLD,ADI,也特别谢谢SOSO姐 。 之前提交的方案,系统比较复杂,时间有限到目前为止完成了部分功能,还没有完全做完,先汇报下一些硬件原理一些相关的。采用双CIS(Contact image sensor)采集的模拟信号经过运放放大到AD的采样的合适 ...…

查看全部问答>

中断按键防抖问题

设定了一个中断按键,低电平触发,但是按键有抖动,按一下键触发好几个中断程序?怎么解决?…

查看全部问答>

初学altera FPGA

刚刚开始接触fpga,用quartus11.1,报错: Error (199067): Quartus II software currently does not support the generation of timing analysis netlists for Cyclone IV E device family Error: Quartus II 64-Bit EDA Netlist Writer was uns ...…

查看全部问答>

平面声音定位系统的程序,求助。

平面声音定位系统的程序,求助。 …

查看全部问答>

【MicroPython】就这么任性

接上一个帖子https://bbs.eeworld.com.cn/thread-489163-1-1.html 上一个程序我们更改了python的main文件,其实可以用更简单快捷的方式完成,即通过串口编辑程序控制LED及其他。你说什么?不信,往下看 Python就是这么任性,把之前的代码在串口 ...…

查看全部问答>

通信协议

请问通信协议在传输的过程中高电平与低电平所持续的时间是固定的吗?打个比方我想做一个两种协议转换的板子,只要把两种协议所需要的端口接到处理器上,并且为处理器搭建好了工作所需的最小系统,这样硬件搭建就可以了吗?两种协议相互转换的功能全 ...…

查看全部问答>