STM32 Flash读写操作详解
文章目录
简介
在STM32芯片内有一个Flash存储器,主要用于存储代码,我们先在电脑上编写程序代码,然后通过下载器把代码烧录到芯片中,这里我们烧录进去的代码其实就是烧录到了Flash中,Flash存储器有一个特点,就是在芯片断电后,里面的数据不会丢失,在重新上电后内核可以从Flash中加载代码并运行。
访问内部Flash的数据速度比外部的SPI-FLASH要快得多,因此,Flash中经常存储一些关键数据,例如:在 RM 比赛中常常将机器人特征数据例(如云台电机中值)保存进 flash。
STM32Flash地址起始于0x0800,结束地址是0x0800加上芯片实际的Flash大小
存储器
存储器分为2种
- 易失性:掉电数据会丢失,通常指RAM(random access memory);
RAM分为SRAM、DRAM
1.SRAM:静态RAM,只要上电数据就不会丢失;
2.DRAM:动态RAM,需要每隔一段时间刷新数据,否则数据会丢失;
- 非易失性:掉电数据仍然可以保存,通常指ROM(read-only memory);
1.最初的ROM只读或可写一次然后只读;
2.后来,发展出电可擦除即EEPROM,从此“ROM只读存储器”只是名义上的只读,实际就是可读可写。EEPROM可对指定字节进入擦除写入。
3.再后来,FLASH闪存出现了,以块为单位擦除,使得存储的数据密度更高,成本更低;
4.FLASH分为Nor FLASH和Nand FLASH:
Nor FLASH可以以字节为单位读取;
Nand FLASH是以块为单位读取数据;
STM32的Flash和SRAM
Flash | SRAM |
---|---|
容量较大(1M) | 容量较小(192kb) |
读取和写入速度较慢 | 读取和写入速度较快 |
掉电不会丢失数据 | 掉电丢失数据 |
分扇区 | 不分扇区 |
写入需要先擦除 | 写入不需擦除 |
存储程序,长时间保存的数据等 | 变量等 |
字节<页(Page)<扇区(Sector)< 块(Block)< 芯片(Chip)
对于Flash的使用:
与Flash相关的函数
flash 擦除函数
HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *SectorError)
函数名 | HAL_FLASHEx_Erase |
---|---|
作用 | 擦除指定的Flash页面(以页为单位) |
返回值 | HAL_StatusTypeDef类型(状态,程序成功执行就返回HAL_OK,失败会返回HAL_ERROR,超时会返回HAL_TIMEOUT) |
参数1 | FLASH_EraseInitTypeDef *pEraseInit,擦除flash时使用的结构体指针,需要创建一个FLASH_EraseInitTypeDef类型的结构体flash_erase,需要赋予这个结构体以下参数:Sector(要擦除的页面的首地址),TypeErase(擦除方式),VoltageRange(电压范围),NbSectors(待擦除页面数),最后我们将&flash_erase作为参数输入函数 |
参数2 | uint32_t *SectorError ,如果本次flash擦除产生了错误,则发生擦除错误的页面号存储在SectorError中。创建一个uint32_t error(存放错误信息的数组),将&error输入即可,如果擦除出错,可以去读取error中的值确认出错的页面号。(0xFFFFFFFFU表示所有扇区都被正确擦除) |
FLASH_EraseInitTypeDef该结构体包含如下:
flash写入函数
HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
函数名 | HAL_FLASH_Program |
---|---|
作用 | 以指定的方式,向flash中的一页写入数据 |
返回值 | HAL_StatusTypeDef类型 |
参数1 | uint32_t TypeProgram,取值为FLASH Type Program类型,FLASH Type Program包括8位字节FLASH_TYPEPROGRAM_BYTE,16位半字FLASH_TYPEPROGRAM_HALFWORD,32位字FLASH_TYPEPROGRAM_WORD,或者64位双字FLASH_TYPEPROGRAM_DOUBLEWORD |
参数2 | uint32_t Address,需要写入数据的地址 |
参数3 | uint64_t Data,需要写入的目标数据 |
FLASH Type Program类型:
flash读取函数
void flash_read(uint32_t address, uint32_t *buf, uint32_t len)
flash的读取相对简单,可以通过memcpy函数进行读取
void flash_read(uint32_t address, uint32_t *buf, uint32_t len)
{
memcpy(buf, (void*)address, len *4);
}
函数名 | flash_read |
---|---|
作用 | 从flash读取数据 |
返回值 | None |
参数1 | Flash地址 |
参数2 | 读取后的存储变量地址 |
参数3 | 字节长度 |
前面讲过Flash有专门的锁寄存器,每次对Flash进行修改时要先通过该寄存器进行解锁,修改后还要进行加锁
相关函数如下:
flash解锁函数
HAL_StatusTypeDef HAL_FLASH_Unlock(void)
函数名 | HAL_FLASH_Unlock |
---|---|
作用 | 为flash解锁,使用户可以修改flash内容 |
返回值 | HAL_StatusTypeDef类型 |
flash加锁函数
HAL_StatusTypeDef HAL_FLASH_Lock(void)
函数名 | HAL_FLASH_Lock |
---|---|
作用 | 为flash加锁,后续操作时只有先解锁才能对flash内容进行修改 |
返回值 | HAL_StatusTypeDef类型 |
本次使用c板进行flash的读写,程序流程如下:
boot作用
boot主要用于控制芯片在上电之后如何引导程序加载到芯片中开始执行。
STM32的启动方式分为三种:
-
最常用的方式,即是从flash中读取烧录的程序,将其引导到STM32中执行。
-
芯片从一块特殊的系统存储区启动,在系统存储区中存有芯片生产厂商已经写好的bootloader程序,这个程序的功能是通过串口将程序读取到flash中去,再将flash中的程序引导到单片机中执行。有一些特殊的下载软件可以让我们通过串口进行STM32程序的下载,其原理就是使用了这种boot方式。使用这种boot的优点是不需要额外的下载器,缺点是下载速度比较慢。
-
从STM32内嵌的SRAM中启动,可以将一小段程序写入SRAM中用于调试,但是因为SRAM的易失性,所以一般不会采用这种方式进行boot,否则每次重新给芯片上电就必须重新给SRAM写入一次程序。
可以通过芯片的boot0和boot1引脚进行设置
方式1 | 方式2 | 方式3 | |
---|---|---|---|
BOOT引脚状态 | BOOT0:GND BOOT1:GND or VCC |
BOOT0:VCC BOOT1:GND |
BOOT0:VCC BOOT1:VCC |
启动区域 | Flash的用户程序存储区 | Bootloader程序存储区 | 内嵌SRAM |
功能 | 将用户通过下载器烧录的程序引导到单片机执行,是最常用的方式 | 通过串口将程序读取到flash中去,再将flash中程序引导到单片机中执行。 | 将SRAM中的程序引导到单片机执行,一般用于调试 |