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

描述

概述

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

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

硬件准备

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

stm32cubemx

视频教学

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

样品申请

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

源码下载

https://download.csdn.net/download/qq_24312945/90228577

参考程序

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

https://gitee.com/CoreMaker/STM32C011_TSSOP20

生成STM32CUBEMX

用STM32CUBEMX生成例程,这里使用MCU为STM32C011F4P6。 配置时钟树,配置时钟为48M。

stm32cubemx

串口配置

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

stm32cubemx

配置串口,速率为115200。

stm32cubemx

堆栈设置

stm32cubemx

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

stm32cubemx

串口重定向

打开魔术棒,勾选MicroLIB

stm32cubemx

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

/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes */

函数声明和串口重定向:

/* 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)。

stm32cubemx

stm32cubemx

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

  1. 解锁 FLASH
  2. 擦除 FLASH
  3. 写入 FLASH
    锁定 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。

/* 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 读写

/* 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: %dn", 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%016llXn", addr + i * 8, data);

    }

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

测试 FLASH 写入和读取功能,分为两次写入操作,并在每次写入后进行验证。 ● 两次写入操作,分别测试不同数据的写入和读取。 ● 验证写入是否正确,通过读取打印结果进行比对。

/* 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 */

演示

测试结果如下所示。

stm32cubemx

第一次写入。

stm32cubemx

第二次写入。

stm32cubemx

STM32CubeProgrammer读取。

stm32cubemx

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
评论(0)
发评论
夏子初 11-27
0 回复 举报
感谢分享 收起回复

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分