三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

STM32H743扩展2MB SRAM全攻略:CubeMX配置、时序优化与性能调优

STM32H743扩展2MB SRAM全攻略:CubeMX配置、时序优化与性能调优

1. 项目概述:为什么需要扩展SRAM?

在嵌入式开发里,尤其是基于STM32这类MCU的项目,内存(RAM)总是一个绕不开的话题。你手头的STM32H743,虽然内部集成了高达1MB的SRAM,听起来已经相当“阔绰”了,但当你真正开始处理一些复杂的应用时,比如运行带GUI的嵌入式系统、处理高分辨率图像、做音频缓冲、或者跑一些复杂的算法模型时,这1MB内存可能瞬间就捉襟见肘了。我最近就遇到了一个项目,需要缓存一帧1024x768的RGB565图像,光这一帧数据就占掉了大约1.5MB的空间,内部SRAM根本不够用。

这时候,外部扩展SRAM就成了一个非常实际且必要的选择。IS61WV204816是一颗非常经典的异步SRAM芯片,容量是16Mbit,也就是2MB。通过STM32H743强大的FMC(Flexible Memory Controller,灵活存储控制器)接口,我们可以很方便地将这片SRAM映射到MCU的地址空间,当作一片高速的、可随机访问的外部内存来使用。整个过程的核心,就是利用CubeMX这个强大的图形化配置工具,把FMC和SRAM的硬件连接“翻译”成正确的初始化代码,省去我们手动翻阅上千页参考手册、逐位配置寄存器的痛苦。

简单来说,这个配置过程就是搭建一座桥,让MCU的核心能顺畅地访问桥对面那片更大的“数据仓库”。下面,我就把从CubeMX配置到代码调试的完整流程,以及我踩过的坑和总结的经验,详细地分享出来。

2. 硬件设计与核心原理拆解

在动手配置软件之前,我们必须先吃透硬件连接和背后的工作原理。这一步如果没搞明白,后面的配置就像在黑暗中摸索,出了问题也很难排查。

2.1 IS61WV204816芯片引脚与FMC接口对应关系

IS61WV204816是一颗16位宽、2MB容量的异步SRAM。它的地址线有18根(A0-A17),可以寻址2^18 * 2字节 = 512K * 2 = 1M个16位字,也就是2MB。数据线是16位(I/O0-I/O15)。关键的控制信号有:

  • /CE (Chip Enable):片选,低电平有效。决定芯片是否被选中。
  • /OE (Output Enable):输出使能,低电平有效。读操作时,需要将此信号拉低,芯片才会把数据放到数据总线上。
  • /WE (Write Enable):写使能,低电平有效。写操作时,需要将此信号拉低,数据总线上的数据才会被写入芯片。
  • /LB (Lower Byte Enable)/UB (Upper Byte Enable):低字节和高字节使能。因为我们用的是16位模式,通常直接将它们接地(始终使能)即可。

STM32H743的FMC接口提供了多种存储器的支持模式,对于异步SRAM,我们通常使用FMC的“NOR/PSRAM”控制器。我们需要在CubeMX中,将MCU的引脚与SRAM芯片的这些信号一一对应起来。

这里有一个非常重要的概念:地址映射。FMC会将外部存储器映射到MCU的固定地址段。对于STM32H743,FMC Bank 1 (NOR/PSRAM 1) 被映射到地址0x6000 0000开始的空间。当我们配置好FMC后,比如我们设置片选信号NE1对应这个Bank,那么访问地址0x6000 0000就相当于向这片SRAM发起了一次访问,FMC硬件会自动产生对应的时序波形(控制信号、地址、数据)。

2.2 FMC时序参数深度解析:如何匹配SRAM芯片手册

这是整个配置中最核心、也最容易出错的部分。异步SRAM没有时钟信号,完全靠控制信号的电平变化来工作。FMC允许我们配置一系列时序参数,来生成符合SRAM芯片要求的读写时序。我们需要仔细阅读IS61WV204816的数据手册,找到关键的时间参数,然后在CubeMX中设置对应的FMC参数。

以IS61WV204816在3.3V供电、速度最慢的型号为例,一些关键参数如下(具体请以你手头芯片的Datasheet为准):

  • tRC (Read Cycle Time):读周期时间,最小45ns。
  • tWC (Write Cycle Time):写周期时间,最小45ns。
  • tAA (Address Access Time):从地址有效到数据输出有效的时间,最大45ns。
  • tOE (Output Enable Access Time):从/OE有效到数据输出有效的时间,最大20ns。
  • tWE (Write Enable Pulse Width):/WE脉冲的宽度,最小35ns。

在CubeMX的FMC配置界面,我们需要关注这几个主要时序设置(以“Mode 1”异步模式为例):

  1. Address Setup Time:地址建立时间。指地址信号有效后,到读/写信号有效之前需要等待的时间。它需要大于SRAM的地址保持时间要求。
  2. Address Hold Time:地址保持时间。指读/写信号无效后,地址信号还需要保持稳定的时间。
  3. Data Setup Time:数据建立时间(写操作)。指数据信号有效后,到写信号结束之前需要保持的时间。需要满足SRAM的tDS(Data Setup Time)要求。
  4. Data Hold Time:数据保持时间(写操作)。指写信号结束后,数据信号还需要保持的时间。需要满足SRAM的tDH(Data Hold Time)要求。
  5. Bus Turn Around Time:总线周转时间。在读写操作切换时,插入的额外延迟周期,防止总线冲突。

如何配置?一个实用的经验法则:在项目初期,或者无法精确计算时,可以采取“保守配置”策略。STM32H743的HCLK时钟通常很高(比如400MHz),一个FMC时钟周期(HCLK)可能只有2.5ns。我们可以先将所有时间参数设置得大一些,确保通信绝对稳定。例如,如果tAA最大是45ns,我们可以设置Data Phase的等待周期为45ns / 2.5ns ≈ 18个周期,在CubeMX中直接设置为18。虽然这会损失一些理论速度,但能极大提高初始调通的概率。等系统稳定后,再根据实际需求和示波器测量,逐步收紧时序,优化性能。

注意:时序配置的单位是“FMC时钟周期数”,而不是纳秒。你需要根据你为FMC外设配置的时钟频率(来源于AHB总线时钟HCLK)来计算一个周期对应的时间。例如HCLK=200MHz,则一个FMC周期为5ns。

2.3 硬件连接检查清单与常见坑点

在连接硬件和配置前,务必对照此清单检查,能避免80%的硬件问题:

  • 电源与地:确保SRAM的VCC(3.3V)和VSS(地)连接稳定,并在芯片电源引脚附近放置一个0.1uF的退耦电容。这是保证信号完整性的基础。
  • 地址线对齐:这是一个经典大坑!FMC的地址线FMC_A[0]应该连接SRAM的A[0]。但因为我们使用的是16位数据宽度,MCU访问是以字节为单位的,而SRAM是以16位字为单位的。这意味着,在软件中,我们访问外部SRAM的地址需要左移一位(乘以2)。例如,你想访问SRAM物理地址0x00001,在程序中应该访问(uint32_t)0x60000000 + (0x00001 << 1)。不过,FMC硬件可以帮我们处理这个偏移,在CubeMX中正确设置数据宽度后,通常不需要手动移位。
  • 控制信号上拉:SRAM的/OE、/WE引脚内部可能是弱上拉或无上拉,建议在PCB设计时,在靠近MCU引脚端为这些信号添加一个4.7K-10K的上拉电阻到3.3V,避免未初始化时的状态不确定。
  • 未用引脚处理:对于IS61WV204816,如果只使用16位模式,/LB和/UB通常直接接地。如果将来可能用到8位模式,则可以连接到FMC的NBL(字节通道)信号。

3. CubeMX图形化配置全流程详解

理论清楚了,我们开始实战。打开STM32CubeMX,创建一个基于STM32H743ZI(或其他H743系列)的新工程。

3.1 引脚分配与FMC外设使能

  1. 时钟配置:首先在Clock Configuration标签页,配置好系统时钟。确保AHB总线时钟(HCLK)是你期望的频率,比如400MHz。FMC的时钟来源于HCLK。
  2. 引脚分配:转到Pinout & Configuration标签页。
    • 在左侧分类中找到FMC并展开。
    • 勾选FMC使能。
    • FMC树下,选择NOR/PSRAM 1。因为我们使用Bank1,对应片选NE1
    • 在右侧的FMC配置界面,Memory type选择SRAM
    • Data选择16 bits
    • 此时,CubeMX会自动为你分配一大片引脚,包括地址线FMC_A[0..xx]、数据线FMC_D[0..15]、写使能FMC_NWE、读使能FMC_NOE、片选FMC_NE1。你可以在芯片图形上看到这些引脚变成了绿色。
    • 重要检查:确认FMC_NE1对应的引脚是否正确(例如PG7)。确认数据线FMC_D0..D15是否连续且没有与其他功能冲突。

3.2 FMC参数精细化配置

FMC配置界面,我们需要仔细设置参数。点击NOR/PSRAM 1,右侧会出现详细的参数选项卡。

  1. Feature选项卡

    • Memory type: SRAM
    • Data: 16 bits
    • Address: 根据你的SRAM容量设置。对于2MB (16Mbit) SRAM,地址线需要18根(A0-A17),但FMC的地址线数量是硬件决定的。对于H743,我们可能只连接了部分地址线(如A0-A15),然后在Memory Size中体现。这里更关键的是Memory Size选项。
    • Memory Size: 选择64 MBytes注意:这个“Memory Size”是FMC Bank的地址空间大小,而不是你物理SRAM的容量。它定义了MCU可以寻址的外部存储区域范围。对于大多数情况,选择64MB或128MB都可以,只要覆盖你的物理地址范围即可。它影响的是地址映射的范围。
    • Burst mode: 对于异步SRAM,禁用(Disable)。
    • Asynchronous Wait: 禁用。我们的SRAM不支持此功能。
    • Write enable: 使能。
    • Extended mode: 禁用。我们使用Mode1或ModeA/B/C/D。
  2. Timing选项卡(重中之重)

    • Address setup time: 根据芯片手册的tAS设置。保守起见可以先设为2个FMC周期。
    • Address hold time: 根据芯片手册的tAH设置。保守起见可以先设为2个周期。
    • Data setup time: 根据芯片手册的tDS(写)和tOE/tAA(读)综合考量。这是最重要的参数之一。对于读操作,Data Phase的持续时间(Data setup time+Bus turnaround time)必须大于tAA。我们可以先设置一个较大的值,比如Data setup time设为10个周期。
    • Data hold time: 根据芯片手册的tDH设置。可以先设为1个周期。
    • Bus turnaround time: 读写切换时的保护间隔,可以先设为1个周期。
    • CLK division: 异步模式不使用时钟,保持默认(Disable)。
    • Data latency: 异步模式不使用,保持默认(0 Cycle)。
    • Access mode: 选择Mode AMode 1。两者时序略有差异,Mode 1是最常见的异步SRAM模式。IS61WV204816通常对应Mode 1请务必核对芯片手册推荐的时序图,选择匹配的模式

    我的经验参数(HCLK=200MHz, FMC周期=5ns, 保守配置)

    • Address setup time: 2
    • Address hold time: 2
    • Data setup time: 15 (对应75ns,远大于45ns的tAA,确保稳定)
    • Data hold time: 1
    • Bus turnaround time: 1
    • Access mode: Mode 1

3.3 生成工程与关键代码解读

配置好所有引脚和FMC后,转到Project Manager标签页,设置好工程名称、路径、IDE(MDK-ARM V5/V6等),然后点击GENERATE CODE

生成代码后,我们重点关注以下几个文件:

  1. fmc.c/fmc.h: 这里包含了FMC的初始化函数MX_FMC_Init()。这个函数根据你在CubeMX中的配置,自动生成了初始化结构体SRAM_HandleTypeDef,并调用了HAL_SRAM_Init()你不需要修改这个函数,但应该理解它做了什么。
  2. main.c: 在main()函数中,系统初始化后会自动调用MX_FMC_Init()

关键点:如何访问外部SRAM?初始化完成后,外部SRAM就被映射到了固定的地址。对于Bank1 NE1,起始地址通常是0x6000 0000。你可以直接通过指针来访问这片内存。

// 定义一个指向外部SRAM起始地址的指针 #define EXT_SRAM_ADDR ((uint32_t)0x60000000) volatile uint16_t *pSram = (volatile uint16_t *)EXT_SRAM_ADDR; // 写入数据 pSram[0] = 0x1234; // 向SRAM的“字地址0”写入0x1234 // 注意:pSram是uint16_t指针,pSram[0]对应SRAM的第一个16位字。 // 如果你想按字节访问,需要定义uint8_t指针,并注意地址对齐。 // 读取数据 uint16_t data = pSram[0];

更规范的做法是使用HAL库提供的函数,这些函数封装了底层访问,并可能处理一些边界情况:

SRAM_HandleTypeDef hsram1; // 这个结构体在fmc.c中已定义并初始化 uint32_t writeData = 0xABCD1234; uint32_t readData = 0; // 使用HAL库函数写入(32位数据,会自动拆成两个16位写入) HAL_SRAM_Write_32b(&hsram1, (uint32_t*)EXT_SRAM_ADDR, &writeData, 1); // 写入1个32位数据 // 使用HAL库函数读取 HAL_SRAM_Read_32b(&hsram1, (uint32_t*)EXT_SRAM_ADDR, &readData, 1); if(readData == writeData) { printf("SRAM读写测试成功!\r\n"); }

4. 软件调试与内存管理实战

配置和编译通过只是第一步,让SRAM真正稳定可靠地工作起来,还需要一系列的软件调试和整合。

4.1 编写SRAM自检函数:确保硬件连接正确

在系统启动后,第一时间对SRAM进行简单的读写测试是非常必要的。这个测试可以快速验证硬件连接、时序配置是否正确。

uint8_t SRAM_Test(void) { volatile uint16_t *p = (volatile uint16_t *)EXT_SRAM_ADDR; uint32_t testSize = 0x1000; // 测试4K个字(8KB),不宜过大,避免耗时过长 uint32_t i; // 1. 写入固定的模式(如递增数) for(i = 0; i < testSize; i++) { p[i] = (uint16_t)i; } // 2. 回读校验 for(i = 0; i < testSize; i++) { if(p[i] != (uint16_t)i) { printf("SRAM测试失败于地址: 0x%08lX, 期望: 0x%04X, 实际: 0x%04X\r\n", (uint32_t)&p[i], (uint16_t)i, p[i]); return 0; // 失败 } } // 3. 反模式测试(可选,检测总线粘连) for(i = 0; i < testSize; i++) { p[i] = ~((uint16_t)i); } for(i = 0; i < testSize; i++) { if(p[i] != ~((uint16_t)i)) { printf("SRAM反模式测试失败于地址: 0x%08lX\r\n", (uint32_t)&p[i]); return 0; } } printf("SRAM自检通过!\r\n"); return 1; // 成功 }

main()函数的初始化部分调用这个函数。如果测试失败,根据打印的地址和错误数据,可以初步判断是地址线、数据线还是控制信号的问题。

4.2 整合到链接脚本:让编译器自动分配变量到外部RAM

对于Keil MDK(ARMCC/AC6)或IAR,我们需要修改链接脚本(Scatter File或ICF文件),将一部分段(section)分配到外部SRAM的地址空间。这里以Keil MDK为例:

  1. 在Keil工程中,打开Options for Target->Linker选项卡。
  2. 取消勾选Use Memory Layout from Target Dialog
  3. 点击Edit...按钮,打开默认的scatter文件进行编辑。
  4. 我们需要添加一个Execution Region,将其地址范围定义在外部SRAM的空间(例如0x600000000x601FFFFF,共2MB)。
  5. 然后,将特定的加载区(LR_)的内容放置到这个执行区域。

一个简化的scatter文件修改示例如下:

LR_IROM1 0x08000000 0x00200000 { ; 内部Flash加载区域 ER_IROM1 0x08000000 0x00200000 { ; 内部Flash执行区域 *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) } RW_IRAM1 0x20000000 0x00020000 { ; 内部DTCM RAM (128KB) .ANY (+RW +ZI) } RW_ERAM1 0x60000000 0x00200000 { ; **新增:外部SRAM执行区域 (2MB)** .ANY (EXTERNAL_RAM) ; 将所有放在`EXTERNAL_RAM`段的内容放到这里 } }

然后,在你的C代码中,通过编译器特性将变量指定到EXTERNAL_RAM段:

// 对于GCC/ARMCC 6 uint32_t large_buffer[102400] __attribute__((section(".EXTERNAL_RAM"), zero_init)); // 对于ARMCC 5 uint32_t large_buffer[102400] __attribute__((at(0x60000000))); // 不推荐,需手动管理地址 // 或者使用更通用的方式(需在链接脚本中定义EXTERNAL_RAM段) #define EXT_RAM __attribute__((section(".EXTERNAL_RAM"))) EXT_RAM uint8_t frame_buffer[1024*768*2]; // 一帧RGB565图像缓冲区

对于STM32CubeIDE(基于GCC),则需要修改STM32H743ZITX_FLASH.ld链接脚本,在MEMORY区域定义外部RAM,并在SECTIONS中创建.external_ram段,并将特定变量分配过去。

4.3 启用缓存(Cache)与MPU配置:提升性能与稳定性

STM32H743具有强大的缓存(I-Cache, D-Cache)和内存保护单元(MPU)。当使用外部存储器时,正确配置它们至关重要。

  • 为什么需要Cache?外部SRAM的访问速度(即使时序优化后)也远慢于内部RAM和CPU核心速度。启用D-Cache(数据缓存)可以将频繁访问的外部RAM数据缓存在芯片内部的高速缓存中,极大提升访问效率,尤其是对于循环、数组遍历等操作。
  • 为什么需要MPU?MPU可以将外部SRAM区域配置为“可缓存”、“可缓冲”、“可共享”等属性。正确的MPU配置是Cache正常工作的前提。通常,我们将外部SRAM区域(如0x60000000-0x601FFFFF)配置为Normal Non-Shared内存,并启用读写缓存(Write-Back, Write-Allocate策略)。

在CubeMX中,可以很方便地启用和配置Cache与MPU:

  1. System Core->Cortex-M7中,勾选ICacheDCacheEnabled
  2. System Core->MPU中,点击Add添加一个新的区域。
    • Base Address:0x60000000
    • Size:2MB(根据你的SRAM大小选择,必须是2的幂次方)
    • Type:Normal
    • Attributes:Outer and inner write-back, write-allocate(通常选择此项以获得最佳性能)
    • Access Permissions:Full access
    • Execute Never:Enabled(建议禁止在此区域执行代码,除非你明确需要XIP)

重要警告:启用Cache后,如果你使用DMA(例如通过DMA2D搬运图像数据到外部SRAM),或者多个核心(如果使用双核芯片)共享这片内存,必须小心缓存一致性问题。CPU写入的数据可能还留在Cache里,没有及时写回外部SRAM,此时DMA读到的就是旧数据。反之,DMA写入的数据,CPU也可能从Cache中读到旧数据。解决方法是,在DMA传输前后,使用SCB_CleanDCache_by_Addr()SCB_InvalidateDCache_by_Addr()函数来清理和无效化缓存中对应地址范围的数据。这是一个高级话题,但一旦用到DMA,就必须处理。

5. 高级应用、性能优化与故障排查

5.1 使用DMA2D加速图形填充与搬运

如果你扩展SRAM是为了图形显示(比如连接LTDC接口的RGB屏),那么STM32H743的DMA2D(2D直接存储器访问)硬件加速器将是你的得力助手。它可以高效地执行颜色填充、图像混合(Alpha Blending)和图像格式转换(如ARGB8888到RGB565)。

假设你的帧缓冲区frame_buffer位于外部SRAM中:

EXT_RAM uint16_t frame_buffer[768][1024]; // 假设屏幕是1024x768 RGB565 // 使用DMA2D将整个屏幕填充为蓝色 void FillScreenBlue(void) { __HAL_RCC_DMA2D_CLK_ENABLE(); // 确保DMA2D时钟已使能 DMA2D_HandleTypeDef hdma2d; hdma2d.Instance = DMA2D; hdma2d.Init.Mode = DMA2D_R2M; // 寄存器到内存模式 hdma2d.Init.ColorMode = DMA2D_OUTPUT_RGB565; hdma2d.Init.OutputOffset = 0; hdma2d.Init.AlphaInverted = DMA2D_REGULAR_ALPHA; hdma2d.Init.RedBlueSwap = DMA2D_RB_REGULAR; hdma2d.Init.AlphaMode = DMA2D_NO_MODIF_ALPHA; HAL_DMA2D_Init(&hdma2d); HAL_DMA2D_Start(&hdma2d, 0x001F, // RGB565蓝色:0b00000_000000_11111 -> 0x001F (uint32_t)frame_buffer, 1024, // 目标行宽度(像素) 768); // 行数 HAL_DMA2D_PollForTransfer(&hdma2d, 100); // 等待传输完成 }

使用DMA2D进行填充或拷贝,速度远超CPU循环,并且不占用CPU资源。切记:如果frame_buffer在带Cache的外部SRAM中,在启动DMA2D传输前,可能需要清理CPU Cache中该区域的数据(如果之前CPU写过);在DMA2D传输完成后,如果需要CPU立即读取新数据,则需要无效化Cache。

5.2 时序优化:从保守到激进

初始保守的时序配置保证了通信的可靠性,但可能限制了SRAM的访问带宽。为了榨取性能,可以进行时序优化:

  1. 理论计算:根据SRAM芯片数据手册的最小时序参数和你的FMC时钟频率,计算出各个参数所需的最小周期数。例如,tAA=45ns,FMC周期=5ns,则Data Phase至少需要45/5 = 9个周期。那么Data setup time可以尝试从15降到10或9。
  2. 逐步收紧:在确保系统功能正常(通过自检函数)的基础上,逐步减小Data setup timeAddress setup/hold time等参数,每次减小1个周期,然后运行一轮完整的SRAM测试(包括边界地址测试、压力测试)。
  3. 示波器验证:这是最可靠的方法。用示波器测量FMC控制信号(如/OE,/WE)和地址/数据线的实际波形,与SRAM数据手册中的时序图进行对比,确保建立时间(tSU)、保持时间(tH)等参数都满足芯片要求,并留有一定余量(比如10%)。
  4. 压力测试:优化后,运行长时间、全地址范围的读写测试,并尝试在CPU高负载、中断频繁的场景下测试,确保没有偶发性的读写错误。

5.3 常见问题排查速查表

问题现象可能原因排查思路与解决方案
SRAM自检失败,数据全为0或0xFF1. 电源或地未连接好。
2. 片选信号/CE未有效拉低。
3. FMC未正确初始化或时钟未使能。
1. 用万用表测量SRAM芯片VCC引脚电压是否为3.3V。
2. 用逻辑分析仪或示波器抓取FMC_NE1片选信号,看在进行访问时是否出现低电平脉冲。
3. 检查main.cMX_FMC_Init()是否被调用,检查FMC外设时钟__HAL_RCC_FMC_CLK_ENABLE()是否已使能。
读写数据不稳定,偶尔出错1. 时序参数太紧,不满足SRAM要求。
2. 信号完整性差(过冲、振铃)。
3. 缓存一致性问题(启用Cache后)。
1. 在CubeMX中增加Data setup timeBus turnaround time,采用更保守的配置。
2. 检查PCB布线,地址/数据线是否过长、有无平行走线过长引起串扰?在信号线上串联小电阻(如22欧姆)有助于改善信号质量。
3. 如果启用了DCache,在DMA传输或双核访问共享内存时,务必进行Cache清理和无效化操作。
只能读写一部分地址,高位地址出错1. 地址线连接错误或虚焊。
2. FMC配置的Memory Size或地址线数量与实际不符。
3. 链接脚本中外部RAM区域定义大小错误。
1. 重点检查高位地址线(如A16, A17)的连接。用自检函数写一个独特的模式到高位地址,用示波器测量对应地址线是否有电平变化。
2. 核对CubeMX中Address线数量配置和Memory Size配置。
3. 检查链接文件中RW_ERAM1区域的大小是否覆盖了整个物理SRAM。
使用HAL库函数读写正常,但直接指针访问出错1. 指针类型定义错误(如用了uint8_t*但数据宽度是16位)。
2. 地址对齐问题。
3. 编译器优化导致访问顺序异常。
1. 确保指针类型与FMC配置的数据宽度匹配(16位SRAM用uint16_t*)。
2. 对于字(16位)访问,地址必须是2字节对齐;对于半字(32位)访问,地址必须是4字节对齐。使用__align(4)等关键字确保缓冲区地址对齐。
3. 尝试在指针访问前使用__DSB()__ISB()内存屏障指令,或者将指针变量声明为volatile
启用Cache后系统运行异常1. MPU未配置或配置错误。
2. 共享内存区域(如DMA缓冲区)未处理缓存一致性。
1. 确保在SystemCoreClock配置之后、使用外部SRAM之前,正确配置了MPU区域(属性为Write-Back等)。
2. 在任何DMA传输开始前,对源缓冲区调用SCB_CleanDCache_by_Addr;在DMA传输完成后,对目标缓冲区调用SCB_InvalidateDCache_by_Addr

配置外部SRAM是一个系统工程,涉及硬件、底层驱动、编译链接和系统配置。按照上述步骤,从硬件原理到CubeMX配置,再到软件调试和高级优化,一步步走下来,基本能解决大部分问题。最关键的还是耐心和细致的排查,特别是硬件连接和时序参数,往往是成败的决定因素。希望这篇长文能帮你顺利在STM32H743上驾驭这片额外的2MB内存空间。

← 返回列表