stm32内部flash在线读写操作

stm32内部flash在线读写操作


✨不同系列,内部flash编程有所区别。例如stm32f1是按照页擦除,半字(16bit)或全字(32bit)数据写入;stm32f4系列按照扇区擦除,可以字节(8bit)、半字(16bit)、字(32bit)和双字(64bit)数据写入.其他系列可以参考对应的参考手册内容说明。

📗stm32内部flash划分

  • 📍STM32F10xxx闪存编程手册:https://picture.iczhiku.com/resource/eetop/WhkWowqdUaYYwcnv.pdf
  • 不同型号的MCU内部flash容量是不同的。STM32F1为例:按照页划分
  • 🌿flash容量低于256KB的,页大小为:1KB=0x400;
  • 🌿flash容量等于或大于256KB的,页大小为:2KB=0x800;
  • 🧨stm32f4xx系列基于扇区操作,含 4 个 16 KB 扇区、1 个 64 KB 扇区 和 7 个 128 KB 扇区。(PM0081编程手册)

📘闪存编程

  • 标准的闪存编程顺序:
  • 检查FLASH_SR寄存器的BSY位,以确认没有其他正在进行的编程操作;
  • 设置FLASH_CR寄存器的PG位为1;
  • 写入要编程的半字到指定的地址;
  • 等待BSY位变为0;
  • 读出写入的地址并验证数据。
  • 注意: 当FLASH_SR寄存器的BSY位为1时,不能对任何寄存器执行写操作。
  • 编程过程流程图:
  • stm32标准库,FLASH编程操作:
c 复制代码
/**
  * 函    数:FLASH编程字
  * 参    数:Address 要写入数据的字地址
  * 参    数:Data 要写入的32位数据
  * 返 回 值:无
  */
void MyFLASH_ProgramWord(uint32_t Address, uint32_t Data)
{
	FLASH_Unlock();							//解锁
	FLASH_ProgramWord(Address, Data);		//编程字
	FLASH_Lock();							//加锁
}

/**
  * 函    数:FLASH编程半字
  * 参    数:Address 要写入数据的半字地址
  * 参    数:Data 要写入的16位数据
  * 返 回 值:无
  */
void MyFLASH_ProgramHalfWord(uint32_t Address, uint16_t Data)
{
	FLASH_Unlock();							//解锁
	FLASH_ProgramHalfWord(Address, Data);	//编程半字
	FLASH_Lock();							//加锁
}
  • HAL库,FLASH编程实现:
c 复制代码
/**
 * @brief 将16位数据写入FLASH
 *
 * @param data 指向要写入的数据的指针
 * @param len 要写入的数据长度(以半字为单位)
 * @param address 写入数据的起始地址
 * @return HAL_StatusTypeDef 返回HAL状态,表示操作是否成功
 */
HAL_StatusTypeDef FLASH_HALFWORD_Write(uint16_t *data, uint16_t len, uint32_t address)
{
    // 解锁FLASH,以便进行写操作
    HAL_FLASH_Unlock();

    // 初始化循环变量
    uint16_t i = 0;

    // 循环写入数据
    for (i = 0; i < len; i++)
    {
        // 对FLASH进行编程,使用HAL_FLASH_Program函数以半字(16位)为单位写入数据
        if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, address, *data) == HAL_OK)
        {
            // 如果写入成功,更新地址和数据指针
            address = address + i * 2; // 地址每次增加2字节(16位)
            data = data + 1;          // 数据指针指向下一个半字
        }
        else
        {
            // 如果写入失败,锁定FLASH并返回错误状态
            HAL_FLASH_Lock();
            return HAL_ERROR;
        }
    }

    // 所有数据写入成功后,锁定FLASH并返回成功状态
    HAL_FLASH_Lock();
    return HAL_OK;
}
/**
 * @brief 将32位数据写入FLASH
 *
 * @param data 指向要写入的数据的指针
 * @param len 要写入的数据长度(以字为单位)
 * @param address 写入数据的起始地址
 * @return HAL_StatusTypeDef 返回HAL状态,表示操作是否成功
 */
HAL_StatusTypeDef FLASH_WORD_Write(uint32_t *data, uint16_t len, uint32_t address)
{
    // 解锁FLASH,以便进行写操作
    HAL_FLASH_Unlock();

    // 初始化循环变量
    uint16_t i = 0;

    // 循环写入数据
    for (i = 0; i < len; i++)
    {
        // 对FLASH进行编程,使用HAL_FLASH_Program函数以字(32位)为单位写入数据
        if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, *data) == HAL_OK)
        {
            // 如果写入成功,更新地址和数据指针
            address = address + i * 4; // 地址每次增加4字节(32位)
            data = data + 1;          // 数据指针指向下一个字
        }
        else
        {
            // 如果写入失败,锁定FLASH并返回错误状态
            HAL_FLASH_Lock();
            return HAL_ERROR;
        }
    }

    // 所有数据写入成功后,锁定FLASH并返回成功状态
    HAL_FLASH_Lock();
    return HAL_OK;
}
信息块的编程
  • 选项字节编程流程::
  • 检查FLASH_SR寄存器的BSY位,以确认没有其他正在进行的编程操作;
  • 设置FLASH_CR寄存器的OPTWRE位为1;
  • 设置FLASH_CR寄存器的OPTPG位为1;
  • 写入要编程的半字到指定的地址;
  • 等待BSY位变为0;
  • 读出写入的地址并验证数据

📒闪存擦除

闪存可以按页擦除,也可以全部擦除。

页擦除

闪存的任何一页都可以通过FPEC的页擦除功能擦除;擦除一页应遵守下述过程:

  • 检查FLASH_SR寄存器的BSY位,以确认没有其他正在进行的闪存操作;
  • 用FLASH_AR寄存器选择要擦除的页;
  • 设置FLASH_CR寄存器的PER位为1;
  • 设置FLASH_CR寄存器的STRT位为1;
  • 等待BSY位变为0;
  • 读出被擦除的页并做验证。
  • 闪存页擦除过程流程图:
  • stm32标准库,FLASH页擦除操作:
c 复制代码
/**
  * 函    数:FLASH页擦除
  * 参    数:PageAddress 要擦除页的页地址
  * 返 回 值:无
  */
void MyFLASH_ErasePage(uint32_t PageAddress)
{
	FLASH_Unlock();					//解锁
	FLASH_ErasePage(PageAddress);	//页擦除
	FLASH_Lock();					//加锁
}
  • HAL库 页擦除操作
c 复制代码
HAL_StatusTypeDef  FLASH_Erase_Page(uint32_t Page_Addr,uint32_t Page_Num)
{
	FLASH_EraseInitTypeDef EraseInitStruct;
	uint32_t PageError = 0;
	HAL_FLASH_Unlock(); //解锁内部flash
	EraseInitStruct.TypeErase     = FLASH_TYPEERASE_PAGES;//标明Flash执行页面只做擦除操作
	EraseInitStruct.PageAddress        = Page_Addr;  //声明要擦除的地址
	EraseInitStruct.NbPages     = Page_Num; //要擦除的页数,此参数必须是Min_Data = 1和Max_Data =(最大页数-初始页的值)之间的值

	if (HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK)
	{
		HAL_FLASH_Lock();
		return HAL_ERROR;
	}
	HAL_FLASH_Lock();
	return HAL_OK;
}
全部擦除

可以用全部擦除功能擦除所有用户区的闪存,信息块不受此操作影响。建议使用下述过程:

  • 检查FLASH_SR寄存器的BSY位,以确认没有其他正在进行的闪存操作;
  • 设置FLASH_CR寄存器的MER位为1;
  • 设置FLASH_CR寄存器的STRT位为1;
  • 等待BSY位变为0;
  • 读出所有页并做验证。
  • 闪存全擦除过程流程图:
  • stm32标准库,FLASH全擦除操作:
c 复制代码
/**
  * 函    数:FLASH全擦除
  * 参    数:无
  * 返 回 值:无
  * 说    明:调用此函数后,FLASH的所有页都会被擦除,包括程序文件本身,擦除后,程序将不复存在
  */
void MyFLASH_EraseAllPages(void)
{
	FLASH_Unlock();					//解锁
	FLASH_EraseAllPages();			//全擦除
	FLASH_Lock();					//加锁
}
  • ⚡需要注意,全擦除,会对内部整个flash进行擦除,擦除后,整个mcu成为空片,原来所烧录的程序将不复存在。如需再使用,需要重新烧录程序。

📙读取操作

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

  • 代码实现:
c 复制代码
/**
  * 函    数:FLASH读取一个32位的字
  * 参    数:Address 要读取数据的字地址
  * 返 回 值:指定地址下的数据
  */
uint32_t MyFLASH_ReadWord(uint32_t Address)
{
	return *((__IO uint32_t *)(Address));	//使用指针访问指定地址下的数据并返回
}

/**
  * 函    数:FLASH读取一个16位的半字
  * 参    数:Address 要读取数据的半字地址
  * 返 回 值:指定地址下的数据
  */
uint16_t MyFLASH_ReadHalfWord(uint32_t Address)
{
	return *((__IO uint16_t *)(Address));	//使用指针访问指定地址下的数据并返回
}

/**
  * 函    数:FLASH读取一个8位的字节
  * 参    数:Address 要读取数据的字节地址
  * 返 回 值:指定地址下的数据
  */
uint8_t MyFLASH_ReadByte(uint32_t Address)
{
	return *((__IO uint8_t *)(Address));	//使用指针访问指定地址下的数据并返回
}

📚相关测试代码

  • 基于STM32F103VC,大容量芯片,页容量2K
  • 🔖HAL库
c 复制代码
通过网盘分享的文件:STM32F103VC_FLASH_Program.rar
链接: https://pan.baidu.com/s/1BrxBfByBddTfv4BUbFdZlA?pwd=3qry 提取码: 3qry
  • 🔖std标准库,基于STM32F103VC,大容量芯片,页容量2K。(参考江协科技代码)
c 复制代码
通过网盘分享的文件:15-1 读写内部FLASH.rar
链接: https://pan.baidu.com/s/115JvFfDWzdurpzlsaiWl6Q?pwd=vepn 提取码: vepn
相关推荐
学生董格22 分钟前
[嵌入式embed]Keil5-STM32F103C8T6(江协科技)+移植RT-Thread v3.15模版
stm32·嵌入式硬件·rt-thread·keil5·江协科技
酷飞飞42 分钟前
掌握DMA基于GD32F407VE的天空星的配置
stm32·单片机·嵌入式硬件·arm
李永奉10 小时前
STM32-认识STM32
stm32·单片机·嵌入式硬件
La Pulga11 小时前
【STM32】I2C通信—软件模拟
c语言·stm32·单片机·嵌入式硬件·mcu
典则1 天前
STM32FreeRtos入门(四)——任务状态和调度
stm32·单片机·嵌入式硬件
充哥单片机设计1 天前
【STM32项目开源】基于STM32的智能天然气火灾监控
stm32·单片机·嵌入式硬件
充哥单片机设计1 天前
【STM32项目开源】基于STM32的智能仓库火灾检测系统
stm32·单片机·嵌入式硬件
就叫飞六吧1 天前
普中stm32大Dap烧录流程
stm32
A9better1 天前
嵌入式开发学习日志38——stm32之看门狗
stm32·嵌入式硬件·学习
小莞尔1 天前
【51单片机】【protues仿真】基于51单片机智能路灯控制系统
c语言·stm32·单片机·嵌入式硬件·51单片机