STM32C011开发(3)----Flash操作

STM32C011开发----3.Flash操作

概述

STM32C011 系列微控制器内置 Flash 存储器,支持程序存储与数据保存,具备页面擦除、双字写入、读写保护等功能。本文将简要介绍 STM32C011 的 Flash 结构与特性,并通过实际代码示例,讲解 Flash 的擦除、写入与读取等基本操作。

最近在弄ST的教程,需要样片的可以加群申请:615061293/925643491 。

硬件准备

首先需要准备一个开发板,这里我准备的是自己绘制的开发板,需要的可以进行申请。

主控为STM32C011F4P6

视频教学

https://www.bilibili.com/video/BV1KTBtY4EpD

STM32C011开发(3)----Flash操作

样品申请

https://www.wjx.top/vm/OhcKxJk.aspx#

源码下载

参考程序

https://github.com/CoreMaker-lab/STM32C011_TSSOP20

https://gitee.com/CoreMaker/STM32C011_TSSOP20

生成STM32CUBEMX

用STM32CUBEMX生成例程,这里使用MCU为STM32C011F4P6。

配置时钟树,配置时钟为48M。

串口配置

查看原理图,PA0和PA1设置为开发板的串口。

配置串口,速率为115200。

堆栈设置

若无法正常运行需要修改优化等级。

串口重定向

打开魔术棒,勾选MicroLIB

在main.c中,添加头文件,若不添加会出现 identifier "FILE" is undefined报错。

c 复制代码
/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes */

函数声明和串口重定向:

c 复制代码
/* USER CODE BEGIN PFP */
int fputc(int ch, FILE *f){
	HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
	return ch;
}
/* USER CODE END PFP */

FLASH

STM32C011 的嵌入式 Flash 通过 AHB 总线与 Cortex-M0+ CPU 连接,支持访问、擦除和编程操作。

Flash 构成:

● 存储单元:Flash 单元为 64 位宽,用于存储代码及数据。

● 主存储器结构:

○ 共 16 页,每页大小为 2 KB,总计 32 KB。

● 信息块区域:

○ 包括选项字节(2 KB)、工程字节(1 KB)、OTP(1 KB)及系统存储器(6 KB)。


要向 FLASH 写入数据,需要依次完成以下四个步骤:

  1. 解锁 FLASH
  2. 擦除 FLASH
  3. 写入 FLASH
  4. 锁定 FLASH
    需要注意,FLASH 的擦除只能按页或整块进行。
    STM32C011F4P6 的 FLASH 容量为 16 KB,共分为 8 页,每页大小为 2 KB。
    我们可以将数据写入第 7 页,其地址范围为 0x08003800 - 0x08003FFF。
    单次写入的单位为 64 位(8 字节)。

数据初始化

● WriteFlashData:

○ 这是一个待写入的 64 位数据数组,包含 3 个双字(64 位)数据。

○ 每个元素的大小是 8 字节,总计 24 字节的数据。

● addr 和 Page:

○ addr 是目标地址,表示从 Flash 的第 7 页(Page 7)开始写入。

○ STM32 的 Flash 以 2 KB 为一页,因此第 7 页的起始地址是 0x08003800。

dart 复制代码
/* USER CODE BEGIN 0 */
uint64_t WriteFlashData[3] = {0x1111222233334444,0x5555666677778888,0x9999AAAABBBBCCCC};//数据

uint32_t addr = 0x08003800;//page 7
uint32_t		Page = 7;

void PrintFlashTest(uint32_t L,uint32_t Page);
void WriteFlashTest(uint32_t L,uint64_t Data[],uint32_t Page,uint32_t addr);

/* USER CODE END 0 */

FLASH 读写

c 复制代码
/* USER CODE BEGIN 4 */
/* FLASH 写入程序 */
void WriteFlashTest(uint32_t L, uint64_t Data[], uint32_t Page, uint32_t addr)
{
    uint32_t i = 0;
    uint32_t PageError = 0;

    // 1/4 解锁 FLASH
    if (HAL_FLASH_Unlock() != HAL_OK)
    {
        printf("Error: Failed to unlock FLASH.\n");
        return;
    }

    // 2/4 初始化擦除结构体并擦除指定页
    FLASH_EraseInitTypeDef FlashSet;
    FlashSet.TypeErase = FLASH_TYPEERASE_PAGES; // 擦除类型:页擦除
    FlashSet.Page = Page;                       // 页索引
    FlashSet.NbPages = 1;                       // 一次擦除 1 页

    if (HAL_FLASHEx_Erase(&FlashSet, &PageError) != HAL_OK)
    {
        printf("Error: Failed to erase FLASH. PageError: %d\n", PageError);
        HAL_FLASH_Lock();
        return;
    }
    printf("FLASH Page %u erased successfully.\n", Page);

    // 3/4 将数据写入指定地址
    for (i = 0; i < L; i++)
    {
        if (HAL_FLASH_Program(TYPEPROGRAM_DOUBLEWORD, addr + 8 * i, Data[i]) != HAL_OK)
        {
            printf("Error: FLASH program failed at address 0x%08X.\n", addr + 8 * i);
            HAL_FLASH_Lock();
            return;
        }
    }
    printf("FLASH programming completed successfully.\n");

    // 4/4 锁住 FLASH
    HAL_FLASH_Lock();
}


/* FLASH 读取并打印程序 */
void PrintFlashTest(uint32_t L, uint32_t addr)
{
    uint32_t i = 0;
    uint64_t data = 0;

    printf("Reading FLASH data from address 0x%08X:\n", addr);

    for (i = 0; i < L; i++)
    {
        data = *(__IO uint64_t *)(addr + i * 8); // 按 64 位读取数据
				printf("Address: 0x%08X, Data: 0x%016llX\n", addr + i * 8, data);

    }

    printf("FLASH read completed.\n");
}
/* USER CODE END 4 */

测试 FLASH 写入和读取功能,分为两次写入操作,并在每次写入后进行验证。

● 两次写入操作,分别测试不同数据的写入和读取。

● 验证写入是否正确,通过读取打印结果进行比对。

c 复制代码
  /* USER CODE BEGIN 2 */
    printf("=== First Write and Read ===\n");
	WriteFlashTest(3,WriteFlashData,Page,addr);
	PrintFlashTest(3,addr);//WriteFlashData[3] = {0x1111222233334444,0x5555666677778888,0x9999AAAABBBBCCCC};//数据
    printf("\n=== Modify Data and Rewrite ===\n");
	WriteFlashData[0]=0x9999;
	WriteFlashData[1]=0x8888;
	WriteFlashData[2]=0x7777;
	WriteFlashTest(3,WriteFlashData,Page,addr);
	PrintFlashTest(3,addr);
  /* USER CODE END 2 */

演示

测试结果如下所示。

第一次写入。

第二次写入。

STM32CubeProgrammer读取。

相关推荐
生活最重要(ง •̀_•́)ง12 天前
[STM32 HAL库]串口中断编程思路
stm32cubemx·stm32 hal库·串口接收数据·编程思路
生活最重要(ง •̀_•́)ง14 天前
[STM32 HAL库]串口空闲中断+DMA接收不定长数据
stm32cubemx·串口空闲中断·stm32 hal库·蓝桥杯嵌入式
瘦弱的皮卡丘21 天前
Adobe Flash,Flash Player和RTMP之间的关系
adobe·rtmp·flash
玄奕子2 个月前
通过Zynq FPGA对雷龙SD NAND进行测试
嵌入式·fpga·flash·sd nand·嵌入式驱动·雷龙
记帖2 个月前
STM32C011开发(2)----nBOOT_SEL设置
stm32cubemx·stm32cubeprog·stm32c011f4p6·nboot_sel·自举模式
记帖3 个月前
STM32WB55RG开发(3)----生成 BLE 程序连接手机APP
蓝牙·stm32cubemx·ipcc·ble·无线·stm32wb55rg·hsem
记帖3 个月前
STM32WB55RG开发(1)----开发板测试
蓝牙·stm32cubemx·ble·无线·stm32wb55rg·开发板测试
记帖3 个月前
STM32H503开发(2)----STM32CubeProgrammer烧录
stm32cubemx·开发板·keil·usb·烧录·stm32h503cb·stm32cubeprog
嵌入式学习和实践3 个月前
stm32 单片机(on-chip flash)(片上flash)使用 rt-thread 的FAL 软件包
stm32·单片机·rt-thread·flash·fal