跳转至

STM32H723VGT6 开发板

STM32H723VGT6 是 ST 高性能系列的 Cortex-M7 芯片,主频高达 550MHz,拥有丰富的外设和大容量存储。相比入门级的 F103,它在算力、内存、外设上都有质的飞跃,但也带来了更复杂的时钟、电源和缓存管理。本页记录该芯片的核心参数、与 F1/F4 的差异以及开发中的关键注意事项。


芯片参数速查

命名解读

STM32 H 723 V G T 6
  │    │  │  │ │ │ │
  │    │  │  │ │ │ └─ 温度范围:6 = -40°C ~ 85°C
  │    │  │  │ │ └─── 封装:T = LQFP
  │    │  │  │ └───── Flash:G = 1MB
  │    │  │  └─────── 引脚数:V = 100 引脚
  │    │  └────────── 系列编号:723
  │    └───────────── 产品线:H = High Performance(高性能)
  └────────────────── ST 32 位微控制器

核心规格

参数 STM32H723VGT6 STM32F103C8T6(对比)
内核 Cortex-M7(DSP + FPU + Cache) Cortex-M3
主频 550 MHz 72 MHz
Flash 1 MB 64 KB
SRAM 564 KB(多区域) 20 KB
L1 Cache 32KB I-Cache + 32KB D-Cache
FPU 双精度(DP-FPU)
DSP
GPIO 最多 82 个 最多 37 个
ADC 3 个 16位 ADC(3.6 MSPS) 2 个 12位 ADC
DAC 2 个 12位 DAC 1 个 12位 DAC
定时器 22 个 7 个
UART/USART 8 个 UART + 4 个 USART 3 个 USART
SPI 6 个(含 OCTOSPI) 2 个
I2C 4 个 2 个
CAN 2 个 FDCAN 1 个 CAN
USB USB 2.0 HS OTG USB 2.0 FS
以太网 10/100M Ethernet MAC
工作电压 1.62V ~ 3.6V 2.0V ~ 3.6V
封装 LQFP100 LQFP48

一句话总结

H723VGT6 的算力是 F103 的 约 30 倍,内存是 28 倍,外设数量翻倍,适合需要高速运算、多外设并行、网络通信的复杂应用(如机器人主控、工业控制、图像处理前端)。100 引脚封装相比 144 引脚版本 GPIO 数量较少(82 vs 114),布局更紧凑,适合空间受限的设计。


内存架构(重点!)

H7 系列最大的不同之一是复杂的多区域 SRAM 架构,理解它对正确使用 DMA 和 FreeRTOS 至关重要。

SRAM 分布

graph TB
    subgraph "STM32H723 内存布局"
        ITCM["ITCM-RAM<br>64 KB<br>0x0000 0000<br>指令紧密耦合"]
        DTCM["DTCM-RAM<br>128 KB<br>0x2000 0000<br>数据紧密耦合"]
        AXI["AXI-SRAM<br>256 KB<br>0x2400 0000<br>通用 SRAM(D1域)"]
        SRAM1["SRAM1<br>16 KB<br>0x3000 0000<br>D2域"]
        SRAM2["SRAM2<br>16 KB<br>0x3000 4000<br>D2域"]
        SRAM4["SRAM4<br>16 KB<br>0x3800 0000<br>D3域"]
        BKPSRAM["Backup SRAM<br>4 KB<br>0x3880 0000<br>电池备份"]
    end
SRAM 区域 大小 地址 特点 典型用途
ITCM-RAM 64 KB 0x0000 0000 CPU 零等待访问,仅 CPU 可访问 关键代码(中断处理函数)
DTCM-RAM 128 KB 0x2000 0000 CPU 零等待访问,DMA 不可访问 任务栈、频繁访问的变量
AXI-SRAM 256 KB 0x2400 0000 CPU 和 DMA 都可访问 FreeRTOS 堆、DMA 缓冲区
SRAM1 16 KB 0x3000 0000 D2 域,DMA 可访问 以太网/USB DMA 缓冲区
SRAM2 16 KB 0x3000 4000 D2 域,DMA 可访问 同上
SRAM4 16 KB 0x3800 0000 D3 域,低功耗保持 低功耗场景数据保持
Backup SRAM 4 KB 0x3880 0000 电池供电保持 RTC 数据、关键参数

最常踩的坑:DTCM 与 DMA

DTCM-RAM(0x2000 0000)虽然速度最快,但DMA 控制器无法访问 DTCM

如果你把 DMA 缓冲区放在 DTCM 中(默认链接脚本可能这样做),DMA 传输会静默失败——数据全是 0 或乱码,且不报错。

解决方案:DMA 缓冲区必须放在 AXI-SRAM(0x2400 0000)或 SRAM1/SRAM2 中。

指定变量到特定 SRAM 区域

/* 方法 1:使用 __attribute__ 指定 section(需要在链接脚本中定义对应段) */

// 放在 AXI-SRAM(DMA 安全)
__attribute__((section(".RAM_D1")))
uint8_t dma_buffer[1024];

// 放在 SRAM1/SRAM2(D2 域,适合以太网/USB DMA)
__attribute__((section(".RAM_D2")))
uint8_t eth_rx_buffer[1536];

// 放在 SRAM4(D3 域)
__attribute__((section(".RAM_D3")))
uint8_t d3_data[256];
/* 方法 2:直接指定地址(简单粗暴) */
uint8_t *dma_buf = (uint8_t*)0x24000000;

CubeMX 生成的链接脚本

CubeMX 为 H7 生成的 .ld 链接脚本已经定义了各 SRAM 区域的段名(如 .RAM_D1.RAM_D2.RAM_D3),可以直接使用 __attribute__((section())) 放置变量。


L1 Cache 管理

为什么 H7 需要关注 Cache?

H723 有 32KB 指令缓存(I-Cache)和 32KB 数据缓存(D-Cache),用于加速 CPU 对内存的访问。但 Cache 带来一个严重问题——数据一致性

sequenceDiagram
    participant CPU as CPU(通过Cache)
    participant Cache as D-Cache
    participant RAM as AXI-SRAM
    participant DMA as DMA 控制器

    Note over CPU,DMA: ⚠️ 问题场景:DMA 接收数据
    DMA->>RAM: DMA 写入新数据到 RAM
    CPU->>Cache: CPU 读取 → 命中缓存旧数据!
    Note over CPU: ❌ CPU 读到的是旧数据
    Note over CPU,DMA: Cache 中的旧数据 ≠ RAM 中的新数据

解决方案

在 DMA 传输前后手动维护 Cache:

/* DMA 发送前:将 Cache 数据写回 RAM */
SCB_CleanDCache_by_Addr((uint32_t*)tx_buffer, sizeof(tx_buffer));
HAL_UART_Transmit_DMA(&huart1, tx_buffer, len);

/* DMA 接收完成后:使 Cache 中对应数据无效化 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    SCB_InvalidateDCache_by_Addr((uint32_t*)rx_buffer, sizeof(rx_buffer));
    // 现在可以安全读取 rx_buffer
}
函数 作用 使用时机
SCB_CleanDCache_by_Addr() 将 Cache 数据写回 RAM DMA 发送前
SCB_InvalidateDCache_by_Addr() 使 Cache 无效,强制从 RAM 重新加载 DMA 接收完成后
SCB_CleanInvalidateDCache_by_Addr() 写回 + 无效化 双向操作时

通过 MPU(Memory Protection Unit)将 DMA 缓冲区所在内存区域标记为不缓存:

/* 在 main.c 中,SystemInit 后配置 MPU */
void MPU_Config(void)
{
    MPU_Region_InitTypeDef MPU_InitStruct = {0};

    HAL_MPU_Disable();

    /* 配置 AXI-SRAM 的某段为 Non-cacheable */
    MPU_InitStruct.Enable = MPU_REGION_ENABLE;
    MPU_InitStruct.BaseAddress = 0x24000000;
    MPU_InitStruct.Size = MPU_REGION_SIZE_256KB;
    MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
    MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
    MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
    MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
    MPU_InitStruct.Number = MPU_REGION_NUMBER0;
    MPU_InitStruct.SubRegionDisable = 0x00;
    MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
    MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
    HAL_MPU_ConfigRegion(&MPU_InitStruct);

    HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
SCB_DisableDCache();  // 简单但性能严重下降

❌ 会让 H7 的性能优势荡然无存,一般不建议。

Cache 对齐要求

Cache 操作以 32 字节为一个 Cache Line。DMA 缓冲区最好 32 字节对齐

/* 32 字节对齐的 DMA 缓冲区 */
__attribute__((aligned(32)))
uint8_t dma_rx_buffer[256];

如果不对齐,SCB_InvalidateDCache_by_Addr() 可能意外覆盖相邻变量。


时钟系统

时钟树概览

H723 的时钟系统比 F1 复杂得多,有 3 个 PLL:

PLL 主要用途 输出
PLL1 系统主时钟 SYSCLK(最高 550MHz)
PLL2 外设时钟 ADC、SPI、I2C、UART 等
PLL3 外设时钟 USB、I2S、SPI 等

CubeMX 时钟配置建议

时钟项 建议值 说明
HSE 8 / 25 MHz 取决于开发板晶振
SYSCLK 550 MHz 最高性能
AHB 275 MHz SYSCLK / 2
APB1 137.5 MHz AHB / 2
APB2 137.5 MHz AHB / 2
APB3 137.5 MHz AHB / 2
APB4 137.5 MHz AHB / 2

CubeMX 自动配置

在 CubeMX 时钟树界面中,输入 SYSCLK 目标频率 550,然后点击 Resolve Clock Issues,CubeMX 会自动计算所有分频/倍频系数。

VOS(Voltage Output Scaling)

H7 运行在高频时需要配置正确的电压等级:

VOS 等级 最高频率 功耗
VOS0 550 MHz 最高
VOS1 400 MHz 较高
VOS2 300 MHz 中等
VOS3 200 MHz 最低

CubeMX 自动处理

CubeMX 在配置 550MHz 主频时会自动设置 VOS0 + PWR 过驱(Overdrive),只需确认电源配置项中 PWR_REGULATOR_VOLTAGE_SCALE0 已启用。


电源域

H723 的外设分布在不同的电源域中:

graph LR
    subgraph D1域(CPU域)
        CPU[Cortex-M7]
        AXI[AXI-SRAM]
        FLASH[Flash]
        DMA2D[DMA2D]
    end

    subgraph D2域(外设域)
        DMA1[DMA1/2]
        ETH[以太网]
        USB_D[USB OTG]
        SPI_D[SPI1-3]
        UART_D[UART/USART]
        TIM_D[TIM1/8/15-17]
    end

    subgraph D3域(低功耗域)
        LPUART[LPUART1]
        I2C4_D[I2C4]
        LPTIM[LPTIM2-5]
        SRAM4_D[SRAM4]
        BDMA[BDMA]
    end

DMA 与电源域的对应关系

  • DMA1/DMA2:只能访问 D1 域(AXI-SRAM)和 D2 域(SRAM1/SRAM2)的内存
  • BDMA:只能访问 D3 域(SRAM4)
  • 跨域 DMA 访问会静默失败!配置 DMA 时必须确保缓冲区在正确的域中

CubeMX 配置注意事项

新建工程检查清单

在 CubeMX 中创建 H723 工程时,以下几项必须检查:

配置项 位置 建议操作
时钟源 RCC → HSE → Crystal 启用外部晶振
Debug SYS → Debug → Serial Wire 否则无法调试
HAL 时基 SYS → Timebase Source 使用 FreeRTOS 时改为 TIM6/7
电压等级 Power → Regulator Voltage VOS0(550MHz必需)
Data Cache Cortex-M7 → CPU D-Cache Enable
Instruction Cache Cortex-M7 → CPU I-Cache Enable
MPU Cortex-M7 → MPU 按需配置(DMA 场景建议启用)
项目堆栈 Project Manager → Linker → Stack/Heap 根据需求调大

与 F1/F4 开发的主要区别

方面 F103/F407 H723 需要注意
Cache 有 I-Cache + D-Cache DMA 必须做 Cache 维护
SRAM 单一区域 多区域(DTCM/AXI/SRAM1-4) DMA 缓冲区不能放 DTCM
Flash 单 Bank 双 Bank 可实现在线升级(OTA)
时钟 1 个 PLL 3 个 PLL 更灵活但更复杂
电源域 单一 D1/D2/D3 三域 DMA 必须匹配电源域
ADC 12位 16位 + 3.6MSPS 精度和速度大幅提升
Ethernet 无/需外挂 内置 MAC 可直接接 PHY 芯片
CAN CAN 2.0 FDCAN 支持灵活数据速率
引脚复用 较少 AF0~AF15,非常灵活 查 datasheet 确认 AF 编号

外设使用提示

UART/USART

/* H723 的 UART 支持更高波特率 */
// APB1 时钟 = 137.5 MHz,理论最高波特率约 8.59 Mbps
// 常用配置:115200 / 921600 / 1000000 / 2000000

/* UART DMA 接收(注意缓冲区位置) */
__attribute__((section(".RAM_D1"), aligned(32)))
uint8_t uart_rx_buf[256];

// 启动空闲中断 + DMA 接收
HAL_UARTEx_ReceiveToIdle_DMA(&huart1, uart_rx_buf, sizeof(uart_rx_buf));

// 接收完成回调
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
    if (huart->Instance == USART1)
    {
        SCB_InvalidateDCache_by_Addr((uint32_t*)uart_rx_buf, sizeof(uart_rx_buf));
        // 处理数据...
        HAL_UARTEx_ReceiveToIdle_DMA(&huart1, uart_rx_buf, sizeof(uart_rx_buf));
    }
}

SPI

/* H723 SPI 支持更高速率 */
// SPI1/2/3 最高 150 MHz(内核时钟 / 分频)
// 实际常用:10 MHz ~ 50 MHz

__attribute__((section(".RAM_D1"), aligned(32)))
uint8_t spi_tx[64], spi_rx[64];

// DMA 发送前 Clean Cache
SCB_CleanDCache_by_Addr((uint32_t*)spi_tx, sizeof(spi_tx));
HAL_SPI_TransmitReceive_DMA(&hspi1, spi_tx, spi_rx, 64);

ADC

/* H723 的 ADC 是 16 位,精度更高 */
// 最大采样率 3.6 MSPS(单通道)
// 分辨率可配置:8/10/12/14/16 位

// CubeMX 中注意:
// - Clock Prescaler: 选择合适的分频
// - Resolution: 16 bits(默认)
// - Conversion Data Management: DMA Circular(连续采集时)

__attribute__((section(".RAM_D1"), aligned(32)))
uint16_t adc_buffer[100];  // 注意:16位分辨率用 uint16_t

HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_buffer, 100);

以太网

/* 以太网 DMA 缓冲区必须在 SRAM1/SRAM2(D2 域) */
__attribute__((section(".RAM_D2")))
uint8_t eth_rx_desc[256];

__attribute__((section(".RAM_D2")))
uint8_t eth_tx_desc[256];

// CubeMX 中配置 ETH 后,使用 LwIP 中间件进行 TCP/IP 通信
// RMII 模式需要连接:RMII_REF_CLK, RMII_MDIO, RMII_MDC,
//                     RMII_CRS_DV, RMII_RXD0, RMII_RXD1,
//                     RMII_TX_EN, RMII_TXD0, RMII_TXD1

调试技巧

确认时钟配置正确

/* 在 main.c 中打印实际时钟频率 */
printf("SYSCLK : %lu MHz\r\n", HAL_RCC_GetSysClockFreq() / 1000000);
printf("HCLK   : %lu MHz\r\n", HAL_RCC_GetHCLKFreq() / 1000000);
printf("APB1   : %lu MHz\r\n", HAL_RCC_GetPCLK1Freq() / 1000000);
printf("APB2   : %lu MHz\r\n", HAL_RCC_GetPCLK2Freq() / 1000000);

查看内存使用情况

编译后查看 .map 文件或 Build Output:

Program Size: Code=xxxx RO-data=xxxx RW-data=xxxx ZI-data=xxxx
  • Code + RO-data = Flash 占用
  • RW-data + ZI-data = SRAM 占用(全局变量 + BSS)
  • 剩余 SRAM = 总 SRAM - 上述值 - 栈 - 堆

常用调试手段

手段 用途 说明
SWD/SWO 下载调试 + 实时追踪 CubeMX 中 SYS → Debug → Serial Wire
ITM printf 无需 UART 的 printf 通过 SWO 引脚输出到调试器
Live Expressions 实时观察变量 Keil/STM32CubeIDE 调试窗口
Fault Analyzer 定位 HardFault STM32CubeIDE 内置

常见问题

程序下载后芯片不运行?

检查清单:

  1. BOOT0 引脚是否接地(从 Flash 启动)
  2. 电源是否稳定(H7 功耗较大,确保供电 ≥ 300mA)
  3. HSE 晶振频率是否与 CubeMX 配置一致
  4. 是否启用了 Debug 接口(SYS → Debug → Serial Wire)

DMA 传输数据全是 0 或乱码?

最常见原因:

  1. 缓冲区在 DTCM 中:DMA 无法访问 DTCM,移到 AXI-SRAM
  2. Cache 一致性:发送前 Clean Cache,接收后 Invalidate Cache
  3. 缓冲区未对齐:加 __attribute__((aligned(32)))
  4. 电源域不匹配:ETH/USB 的 DMA 缓冲区应在 D2 域(SRAM1/SRAM2)

H7 比 F4 慢?性能没提升?

可能原因:

  • D-Cache 未启用SCB_EnableDCache() 是否在 SystemInit 中调用
  • I-Cache 未启用SCB_EnableICache() 同理
  • VOS 等级过低:未设置 VOS0 导致主频被限制
  • Flash 等待周期:高频下 Flash Wait States 需要正确配置(CubeMX 自动处理)
  • ART Accelerator 未启用:检查 Flash ACR 寄存器

从 F1/F4 项目迁移到 H7 有哪些坑?

主要注意点:

  • 所有 DMA 缓冲区不能放在默认 SRAM(DTCM)
  • 使用 DMA 时必须处理 Cache 一致性
  • 外设时钟频率不同,UART 波特率、SPI 分频需要重新计算
  • GPIO 引脚的复用功能编号(AF)不同,必须查 H723 的 datasheet
  • HAL_Delay() 精度可能受 VOS/时钟配置影响
  • 链接脚本需要关注内存分区,默认可能只用了 DTCM