问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

STM32 DMA烧录实战教程

创作时间:
作者:
@小白创作中心

STM32 DMA烧录实战教程

引用
CSDN
9
来源
1.
https://blog.csdn.net/as480133937/article/details/104927922
2.
https://blog.csdn.net/fengel_cs/article/details/123511474
3.
https://blog.csdn.net/modi000/article/details/115006407
4.
https://blog.csdn.net/weixin_44524484/article/details/105671273
5.
https://blog.csdn.net/xieliru/article/details/139897929
6.
https://blog.51cto.com/u_16213429/12012416
7.
https://blog.csdn.net/qq_48361010/article/details/134240753
8.
https://www.cnblogs.com/SymPny/p/17570236.html
9.
https://www.cnblogs.com/schips/p/8215711.html
01

硬件准备和连接

在开始STM32 DMA烧录之前,首先需要准备以下硬件设备:

  1. STM32开发板(推荐使用STM32F4系列)
  2. ST-Link烧录器(支持SWD或JTAG接口)
  3. USB线和排线

硬件连接步骤:

  1. 将ST-Link烧录器通过USB线连接到电脑
  2. 使用排线将ST-Link烧录器与STM32开发板连接,连接方式如下:
ST-Link引脚
STM32开发板引脚
GND
GND
3.3V
3.3V
SWDIO
PA13 (SWDIO)
SWCLK
PA14 (SWCLK)

02

软件开发环境搭建

安装开发工具:

  1. 下载并安装STM32CubeMX:STM32CubeMX下载链接
  2. 下载并安装Keil MDK:Keil MDK下载链接

配置开发环境:

  1. 打开STM32CubeMX,选择你的STM32型号
  2. 配置时钟树,确保系统时钟设置正确
  3. 生成代码,选择Keil MDK作为工具链
  4. 打开生成的Keil项目,确保HAL库已正确集成
03

代码实现详解

DMA控制器配置:

在开始DMA烧录之前,需要对DMA控制器进行配置。以下是一个基本的DMA配置示例:

#include "stm32f4xx_hal.h"

// 定义烧录参数
#define BIN_FILE_ADDR    0x08010000   // Flash目标地址(需与链接脚本对齐)
#define BIN_BUFFER_SIZE  1024         // DMA缓冲区大小

// DMA传输控制结构体
typedef struct {
    uint8_t* bin_data;         // BIN文件数据指针
    uint32_t file_size;        // 文件总大小
    uint32_t transferred;      // 已传输字节数
    DMA_HandleTypeDef hdma;    // DMA句柄
} FlashProgramTypeDef;

// 初始化DMA配置
void DMA_Init(FlashProgramTypeDef* prog) {
    __HAL_RCC_DMA2_CLK_ENABLE();
    
    prog->hdma.Instance = DMA2_Stream0;          // 根据硬件连接选择DMA通道
    prog->hdma.Init.Channel = DMA_CHANNEL_0;     // 外设通道号
    prog->hdma.Init.Direction = DMA_MEMORY_TO_MEMORY; // 内存到内存传输
    prog->hdma.Init.PeriphInc = DMA_PINC_ENABLE;
    prog->hdma.Init.MemInc = DMA_MINC_ENABLE;
    prog->hdma.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
    prog->hdma.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
    prog->hdma.Init.Mode = DMA_NORMAL;
    prog->hdma.Init.Priority = DMA_PRIORITY_HIGH;
    HAL_DMA_Init(&prog->hdma);
}

BIN文件烧录代码:

// 烧录函数
HAL_StatusTypeDef Program_Flash(FlashProgramTypeDef* prog) {
    HAL_StatusTypeDef status;
    
    // 解锁Flash
    HAL_FLASH_Unlock();
    
    // 分块烧录(适配DMA缓冲区大小)
    for(uint32_t i=0; i<prog->file_size; i+=BIN_BUFFER_SIZE){
        uint32_t chunk_size = (prog->file_size - i) > BIN_BUFFER_SIZE ? 
                             BIN_BUFFER_SIZE : (prog->file_size - i);
                             
        // 启动DMA传输
        status = HAL_DMA_Start(&prog->hdma, 
                             (uint32_t)(prog->bin_data + i), 
                             (uint32_t)(BIN_FILE_ADDR + i), 
                             chunk_size/4);  // 按字传输
        if(status != HAL_OK) break;
        
        // 等待传输完成
        HAL_DMA_PollForTransfer(&prog->hdma, HAL_DMA_FULL_TRANSFER, 1000);
        
        // 校验数据
        if(memcmp(prog->bin_data + i, (void*)(BIN_FILE_ADDR + i), chunk_size) != 0){
            status = HAL_ERROR;
            break;
        }
    }
    
    HAL_FLASH_Lock();
    return status;
}

// 主函数示例
int main(void) {
    FlashProgramTypeDef programmer;
    
    // 初始化系统时钟等...
    HAL_Init();
    SystemClock_Config();
    
    // 加载BIN文件到内存(需实现文件读取逻辑)
    programmer.bin_data = Load_BIN_File("firmware.bin", &programmer.file_size);
    
    // 初始化DMA
    DMA_Init(&programmer);
    
    // 执行烧录
    if(Program_Flash(&programmer) == HAL_OK) {
        printf("烧录成功!\n");
    } else {
        printf("烧录失败!\n");
    }
    
    while(1);
}
04

实际操作步骤

  1. 将编译好的BIN文件加载到STM32的RAM中
  2. 配置DMA控制器,设置源地址为RAM中的BIN文件地址,目标地址为Flash目标地址
  3. 启动DMA传输,等待传输完成
  4. 校验烧录结果,确保数据正确写入Flash
05

常见问题和解决方案

  1. 问题:烧录失败

    • 检查硬件连接是否正确
    • 确保BIN文件地址与Flash目标地址对齐
    • 检查DMA配置参数是否正确
  2. 问题:数据校验失败

    • 确保DMA传输完成后Flash已正确锁定
    • 检查校验逻辑是否正确
  3. 问题:烧录过程卡死

    • 检查DMA中断配置是否正确
    • 确保系统时钟配置正确
06

注意事项

  1. 确保目标地址避开Bootloader区域
  2. DMA传输大小需为字对齐(4字节)
  3. 实际应用中需添加超时重试机制
  4. 建议添加CRC校验机制以确保数据完整性

通过以上步骤,你可以实现基于STM32的DMA烧录功能。这个过程虽然涉及多个环节,但通过详细的配置和调试,可以实现高效的数据传输和程序烧录。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号