打印
[STM32F3]

如何使用 STM32 CubeMX 配置并生成 Flash 操作的代码

[复制链接]
52|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
初级工程渣|  楼主 | 2024-9-30 18:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在 STM32 的应用中,使用 CubeMX 配置和生成 Flash 读写操作的代码可以简化开发流程。STM32 CubeMX 是 ST 提供的图形化配置工具,可以帮助用户生成初始化代码,并与 HAL 库结合使用,方便开发 Flash 的擦除、写入和读取操作。下面我将详细讲解如何使用 STM32 CubeMX 配置并生成 Flash 操作的代码

使用特权

评论回复
沙发
初级工程渣|  楼主 | 2024-9-30 18:14 | 只看该作者
使用 STM32 CubeMX 配置工程
1.1 创建新的项目
打开 STM32 CubeMX,选择目标 STM32 芯片或开发板(例如 STM32F4 系列)。
点击 "Project" > "New Project",然后在芯片选择界面中选择所需的 MCU 或开发板。

使用特权

评论回复
板凳
初级工程渣|  楼主 | 2024-9-30 18:14 | 只看该作者
配置时钟
在 CubeMX 界面的 "Pinout & Configuration" 标签下,配置所需的时钟树。在大多数项目中,外部振荡器(HSE)是常见的选择,配置时确保时钟频率符合 Flash 写操作的要求(大多数 STM32 Flash 操作都在系统时钟频率较低时更加稳定)。
在 "Clock Configuration" 中配置系统时钟(通常可以使用默认设置,但应确保时钟频率不超过 MCU 的限制)。

使用特权

评论回复
地板
初级工程渣|  楼主 | 2024-9-30 18:14 | 只看该作者
启用 Flash 预取缓冲区
为了优化读取操作,可以启用 Flash 预取缓冲区和缓存。

在 CubeMX 的 "Configuration" 选项中找到 "Flash" 配置。
启用 Instruction Cache 和 Data Cache。
启用 Prefetch Buffer 以提高 Flash 的读取性能。

使用特权

评论回复
5
初级工程渣|  楼主 | 2024-9-30 18:14 | 只看该作者
生成代码
配置完成后,点击 "Project" 菜单中的 "Generate Code",生成代码。在生成代码时,选择 MDK-ARM、STM32CubeIDE 或其他 IDE 作为工具链,并为项目命名。
代码生成后,打开指定的 IDE,导入项目。

使用特权

评论回复
6
初级工程渣|  楼主 | 2024-9-30 18:14 | 只看该作者
CubeMX 生成的代码结构
生成的代码主要位于 Src 和 Inc 目录下,其中和 Flash 相关的文件通常包含以下内容:

main.c:主循环和初始化代码。
stm32f4xx_hal_flash.c:提供了 HAL 库的 Flash 操作函数,例如 Flash 解锁、擦除、编程等操作。

使用特权

评论回复
7
初级工程渣|  楼主 | 2024-9-30 18:14 | 只看该作者
在 main.c 中会有如下初始化代码:

c/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();

/* Configure the system clock */
SystemClock_Config();

/* Initialize all configured peripherals */
MX_GPIO_Init();  // 如果有其他外设,会有相应初始化代码

使用特权

评论回复
8
初级工程渣|  楼主 | 2024-9-30 18:14 | 只看该作者
Flash 操作代码示例
STM32 CubeMX 自动生成的项目并不会包含具体的 Flash 读写操作代码,你需要手动编写基于 HAL 库的 Flash 操作函数。以下是如何在 CubeMX 生成的基础代码上,加入 Flash 擦除、写入和读取操作的详细步骤。

使用特权

评论回复
9
初级工程渣|  楼主 | 2024-9-30 18:14 | 只看该作者
Flash 解锁与锁定
在进行 Flash 写操作之前,需要先解锁 Flash 寄存器,操作完成后再锁定以防止误写。

cHAL_FLASH_Unlock();  // 解锁 Flash
HAL_FLASH_Lock();    // 写入结束后锁定 Flash

使用特权

评论回复
10
初级工程渣|  楼主 | 2024-9-30 18:14 | 只看该作者
Flash 擦除操作
擦除 Flash 是以页为单位的。STM32 Flash 的擦除操作比较耗时,因此应尽量减少擦除次数。可以使用 HAL 提供的 HAL_FLASHEx_Erase() 函数来擦除 Flash 页。

cvoid Flash_Erase(uint32_t PageAddress)
{
    FLASH_EraseInitTypeDef EraseInitStruct;
    uint32_t PageError = 0;

    // 配置擦除类型和扇区
    EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
    EraseInitStruct.Sector = FLASH_SECTOR_5; // 根据需要选择扇区
    EraseInitStruct.NbSectors = 1;           // 只擦除1个扇区
    EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;

    HAL_FLASH_Unlock();  // 解锁 Flash

    // 擦除指定的扇区
    if (HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK)
    {
        // 处理擦除错误
        Error_Handler();
    }

    HAL_FLASH_Lock();  // 擦除后锁定 Flash
}

使用特权

评论回复
11
初级工程渣|  楼主 | 2024-9-30 18:15 | 只看该作者
Flash 写入操作
写入 Flash 是以 32 位(word)为单位的。可以使用 HAL_FLASH_Program() 来将数据写入到 Flash。

cvoid Flash_Write(uint32_t Address, uint32_t Data)
{
    HAL_FLASH_Unlock();  // 解锁 Flash

    // 写入 32 位数据
    if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Address, Data) != HAL_OK)
    {
        // 处理写入错误
        Error_Handler();
    }

    HAL_FLASH_Lock();  // 写入完成后锁定 Flash
}

使用特权

评论回复
12
初级工程渣|  楼主 | 2024-9-30 18:15 | 只看该作者
Flash 读取操作
Flash 的读取操作可以直接通过内存映射的方式读取指定地址的数据:

cuint32_t Flash_Read(uint32_t Address)
{
    return *(__IO uint32_t*)Address;  // 直接读取指定地址处的数据
}

使用特权

评论回复
13
初级工程渣|  楼主 | 2024-9-30 18:15 | 只看该作者
示例代码整合
以下是一个完整的示例,展示如何使用 Flash 擦除、写入和读取操作:

cint main(void)
{
    // 初始化 HAL 库
    HAL_Init();

    // 初始化时钟
    SystemClock_Config();

    // 定义需要写入和读取的地址和数据
    uint32_t flash_address = 0x08020000;  // 自定义的 Flash 地址
    uint32_t write_data = 0x12345678;     // 需要写入的数据
    uint32_t read_data;

    // 擦除指定的 Flash 页
    Flash_Erase(flash_address);

    // 写入数据到 Flash
    Flash_Write(flash_address, write_data);

    // 从 Flash 中读取数据
    read_data = Flash_Read(flash_address);

    // 检查数据是否写入成功
    if (read_data == write_data)
    {
        // 数据写入正确
    }
    else
    {
        // 处理写入错误
        Error_Handler();
    }

    while (1)
    {
        // 主循环
    }
}

使用特权

评论回复
14
初级工程渣|  楼主 | 2024-9-30 18:15 | 只看该作者
常见问题与优化建议
4.1 时钟配置
确保时钟配置正确,尤其是在 Flash 写入时。时钟频率过高可能导致 Flash 写入不稳定。

使用特权

评论回复
15
初级工程渣|  楼主 | 2024-9-30 18:15 | 只看该作者
中断管理
Flash 写入期间,Flash 存储区域被占用,因此要避免在写入过程中执行从 Flash 加载的中断服务程序(ISR)。可以暂时禁用中断或者确保 ISR 在 RAM 中运行。

c__disable_irq();  // 禁用中断
// Flash 操作
__enable_irq();   // 重新启用中断

使用特权

评论回复
16
初级工程渣|  楼主 | 2024-9-30 18:15 | 只看该作者
扇区擦除
尽量避免频繁擦除整个扇区,因为擦除操作较慢且会影响 Flash 的寿命。可以通过在擦除前检查该页是否已经写入数据来减少不必要的擦除操作。

使用特权

评论回复
17
初级工程渣|  楼主 | 2024-9-30 18:15 | 只看该作者
通过 STM32 CubeMX 配置和生成代码,并结合 HAL 库的 Flash 操作函数,可以轻松地在 STM32 中实现 Flash 的读写操作。具体步骤如下:

使用 CubeMX 配置项目和时钟。
编写 Flash 擦除、写入和读取操作的函数。
在 main.c 中调用相应的 Flash 操作函数。
这样可以高效地实现 Flash 读写,并应用于嵌入式系统中数据的持久化存储任务。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

57

主题

655

帖子

0

粉丝